

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=&#34;auto&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/blog/img/favicon.png">
  <link rel="icon" href="/blog/img/favicon.jpg">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="">
  <meta name="author" content="John Doe">
  <meta name="keywords" content="">
  
  <title>JavaScript笔记-2 - ITaylorfan的小站</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/blog/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10.7.2/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
  



<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/blog/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"itaylorfan.gitee.io","root":"/blog/","version":"1.8.11","typing":{"enable":true,"typeSpeed":70,"cursorChar":"❤","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null}},"search_path":"/local-search.xml"};
  </script>
  <script  src="/blog/js/utils.js" ></script>
  <script  src="/blog/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 5.4.0"></head>


<body>
  <header style="height: 85vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/blog/">&nbsp;<strong>ITaylorfan</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/blog/img/TS8-10-9.jpg') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="JavaScript笔记-2">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2021-09-12 23:36" pubdate>
        2021年9月12日 晚上
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      22.4k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      275
       分钟
    </span>
  

  
  
</div>

            
          </div>

          
            <div class="scroll-down-bar">
              <i class="iconfont icon-arrowdown"></i>
            </div>
          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">JavaScript笔记-2</h1>
            
            <div class="markdown-body">
              <h1 id="前端基础-JavaScript-2"><a href="#前端基础-JavaScript-2" class="headerlink" title="前端基础-JavaScript-2"></a>前端基础-JavaScript-2</h1><h2 id="1-面向对象"><a href="#1-面向对象" class="headerlink" title="1.面向对象"></a>1.面向对象</h2><p>如果它是一个对象，那么它应该具备 以下几个特点</p>
<ol>
<li><p>对象具备属性</p>
<p>属性就是用于描述当前对象的特征的，可以理解为上在面的【数据】</p>
</li>
<li><p>对象具备方法</p>
<p>方法就是一个对象的能力，例如它可以做什么事情。可以理解为上面的【能力】</p>
</li>
<li><p>对象应该是可以继承的</p>
<p>父级对象里面的某些方法或属性或以在子级对象里面，继续使用</p>
</li>
</ol>
<h3 id="1-1对象的创建"><a href="#1-1对象的创建" class="headerlink" title="1.1对象的创建"></a>1.1对象的创建</h3><p>对象的创建可以理解为对象的封装</p>
<h4 id="通过键值对创建"><a href="#通过键值对创建" class="headerlink" title="通过键值对创建"></a>通过键值对创建</h4><p>在JavaScript里面，键(key)就是我们的属性名，值(value)也叫对象的属性值，键值对的创建方式就是属性名与属性值的方式在创建，它的语法格式如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> 对象名 = &#123;<br>    属性名<span class="hljs-number">1</span>:属性值<span class="hljs-number">1</span>,<br>    属性名<span class="hljs-number">2</span>:属性值<span class="hljs-number">2</span><br>    <span class="hljs-comment">//......</span><br>&#125;;<br></code></pre></td></tr></table></figure>

<p>上面就是键值对创建对象方式的基本语法，现在我们把刚刚的学生信息来使用对象的方式集中管理数据</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu1 = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;刘佳欣&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;女&quot;</span>,<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">18</span>,<br>    <span class="hljs-attr">hobby</span>: <span class="hljs-string">&quot;范绪超&quot;</span><br>&#125;;<br><br><br><span class="hljs-keyword">var</span> stu2 = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;钟宇飞&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;男&quot;</span>,<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">19</span>,<br>    <span class="hljs-attr">hobby</span>: <span class="hljs-string">&quot;打球&quot;</span><br>&#125;;<br></code></pre></td></tr></table></figure>

<blockquote>
<p><strong>代码分析</strong>：</p>
<p>在上面的代码里面，我们一共才定义了两个变量，分别是<code>stu1</code>与<code>stu2</code>，它们都是对象，在这个对象的内部，我们又分别各添加了4个属性<code>name,sex,age,hobby</code>用于记录这个对象的基本信息（数据）。所以这个时候当我们再去管理学生的时候我们只需要管理<code>stu1,stu2</code> 这两个对象的变量就可以了，其它的可以忽略了，这术是<strong>高内聚，低耦合</strong>的特点</p>
</blockquote>
<p>对象中创建方法</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu1 = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;刘佳欣&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;女&quot;</span>,<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">18</span>,<br>    <span class="hljs-attr">hobby</span>: <span class="hljs-string">&quot;范绪超&quot;</span>,<br>    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-comment">//把一个匿名函数赋值给了属性名</span><br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;我是一个方法&quot;</span>);<br>    &#125;<br>&#125;;<br></code></pre></td></tr></table></figure>

<p>使用<code>this</code>关键字(指针)，调用对象中自己的属性</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu1 = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;刘佳欣&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;女&quot;</span>,<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">18</span>,<br>    <span class="hljs-attr">hobby</span>: <span class="hljs-string">&quot;范绪超&quot;</span>,<br>    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我叫&quot;</span> + <span class="hljs-built_in">this</span>.name);  <span class="hljs-comment">//使用this</span><br>        <span class="hljs-built_in">this</span>.abc();   	<span class="hljs-comment">//使用this</span><br>    &#125;,<br>    <span class="hljs-attr">abc</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123; <br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;abc&quot;</span>);<br>    &#125;<br>&#125;;<br></code></pre></td></tr></table></figure>

<h4 id="通过Object创建"><a href="#通过Object创建" class="headerlink" title="通过Object创建"></a>通过<code>Object</code>创建</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Object</span>();         <span class="hljs-comment">//它就得到了一个花括号</span><br></code></pre></td></tr></table></figure>

<p>这一种方式只要与我们的数组的方式相结合就很好理解了</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>();			<span class="hljs-comment">//得到的是[]     得到了一个空的数组</span><br><span class="hljs-keyword">new</span> <span class="hljs-built_in">Object</span>();			<span class="hljs-comment">//得到一个&#123;&#125;	 得到了一个空的对象</span><br></code></pre></td></tr></table></figure>

<p>得到这个空的对象，向对象中添加值</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Object</span>(); <span class="hljs-comment">//它就得到了一个花括号，也就是一个空的对象</span><br><span class="hljs-comment">//在空的对象上面动态的添加所需要的属性</span><br>obj.name = <span class="hljs-string">&quot;郭磊磊&quot;</span>;<br>obj.sex = <span class="hljs-string">&quot;男&quot;</span>;<br>obj.age = <span class="hljs-number">18</span>;<br>obj[<span class="hljs-number">123</span>] = <span class="hljs-string">&quot;hello&quot;</span>;		<span class="hljs-comment">//特殊属性的使用</span><br>obj.sayHello = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我叫&quot;</span> + <span class="hljs-built_in">this</span>.name);<br>&#125;<br></code></pre></td></tr></table></figure>

<p>上面的2种方式都可以帮我们快速的创建对象，但是我们仍然有一个问题，当我们如果需要创建很多对象的时候就会很麻烦。</p>
<p>我们现在需要有一种技术，快速构建这一种结构相同的对象。</p>
<h4 id="使用工厂模式创建对象"><a href="#使用工厂模式创建对象" class="headerlink" title="使用工厂模式创建对象"></a>使用工厂模式创建对象</h4><blockquote>
<p>一提起工厂，我们的脑海里面就有画面了。工厂给我们的感觉就是批量去创建东西的，我们现在就是需要批量的创建东西，并且创建的东西格式都相同</p>
<p><strong>本方法只做了解，后期不要使用这个方法</strong></p>
</blockquote>
<p>使用工厂方法快速创建学生对象</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//现在先编写一个方法，专用用于创建对象</span><br><span class="hljs-comment">//现在要批量的创建学生</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createStudent</span>(<span class="hljs-params">_name, _sex, _age</span>) </span>&#123;<br>    <span class="hljs-keyword">var</span> obj = &#123;<br>        <span class="hljs-attr">name</span>: _name,<br>        <span class="hljs-attr">sex</span>: _sex,<br>        <span class="hljs-attr">age</span>: _age,<br>        <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我叫&quot;</span> + <span class="hljs-built_in">this</span>.name);<br>        &#125;<br>    &#125;;<br>    <span class="hljs-comment">//把这个对象返回到外边去</span><br>    <span class="hljs-keyword">return</span> obj;<br>&#125;<br><span class="hljs-keyword">var</span> stu1 = createStudent(<span class="hljs-string">&quot;韩文君&quot;</span>, <span class="hljs-string">&quot;女&quot;</span>, <span class="hljs-number">18</span>); <span class="hljs-comment">//这个时候就得到了一个对象</span><br><span class="hljs-keyword">var</span> stu2 = createStudent(<span class="hljs-string">&quot;高远航&quot;</span>, <span class="hljs-string">&quot;男&quot;</span>, <span class="hljs-number">19</span>);<br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/61204fed4907e2d39cc51674.png" srcset="/blog/img/loading.gif" lazyload></p>
<p><strong>工厂模式的缺点：无法辨识对象的类别</strong></p>
<hr>
<h4 id="使用构造函数创建对象【重点】"><a href="#使用构造函数创建对象【重点】" class="headerlink" title="使用构造函数创建对象【重点】"></a>使用构造函数创建对象【重点】</h4><blockquote>
<p><strong>本章是重点，重点中的重点，重要的事情一定要说三遍</strong></p>
</blockquote>
<p>要弄清楚构造函数，先要弄清楚什么是构造函数？</p>
<p>函数我们之前都已经学习过了，它是通过<code>function</code>来进行定义，同时我们也学习了函数的调用方式，目前函数的调用方式有如下几种</p>
<pre><code class=" mermaid">graph LR
A((函数地调用))--&gt;B[&quot;函数名+()&quot;]
A--&gt;C[&quot;var 函数名 = function()&#123;&#125;()&quot;]
A--&gt;D[&quot;立即执行函数+function()&#123;&#125;()&quot;]
A--&gt;E[&quot;闭包(function()&#123;&#125;)()&quot;]
A--&gt;F[&quot;new 函数名() 构造函数调用&quot;]
</code></pre>

<p>上面的4种是我们之前所学习的函数的调用方式，但是今天要讲的可以又是一种函数的调用方式，首先，我们先看下面的代码</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(<span class="hljs-string">&quot;a&quot;</span>,<span class="hljs-string">&quot;b&quot;</span>,<span class="hljs-string">&quot;c&quot;</span>,<span class="hljs-string">&quot;d&quot;</span>,<span class="hljs-string">&quot;e&quot;</span>);		<span class="hljs-comment">//创建了一个数组</span><br><span class="hljs-keyword">var</span> obj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Object</span>();							<span class="hljs-comment">//创建了一个对象</span><br></code></pre></td></tr></table></figure>

<p>上面的两行代码大家都很熟悉，一个是创建数组，一个是创建空对象，这个时候我们2个疑问</p>
<ol>
<li>为什么需要<code>new</code>这一个关键字？</li>
<li><code>Array</code>与<code>Object</code>到底是什么，为什么后面有括号？</li>
</ol>
<p>如果把这两个点弄通弄透了，我们的构造函数就出来了</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">Array</span>);				<span class="hljs-comment">//function</span><br><span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">Object</span>);				<span class="hljs-comment">//function</span><br></code></pre></td></tr></table></figure>

<p>这个时候我们可以看到<code>new</code>关键后面跟的<code>Array</code>与<code>Object</code>都是一个<code>function</code>，这个时候就要知道了<code>Array</code>与<code>Object</code>都是内置的构造函数</p>
<p><strong>所谓的构造函数其实与普通函数没有任何区别，只是它们的调用方式不一样了，<span style="color:red;">如果一个函数使用了<code>new</code>的关键字去调用，这个函数就叫构造函数</span></strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sayHello</span>(<span class="hljs-params"></span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我是标哥&quot;</span>);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">123</span>;<br>&#125;<br><span class="hljs-comment">//以普通方式在调用函数</span><br><span class="hljs-keyword">var</span> a = sayHello();         <span class="hljs-comment">//返回的结果就是123</span><br><br><span class="hljs-comment">//以构造函数的形式去调用</span><br><span class="hljs-keyword">var</span> b = <span class="hljs-keyword">new</span> sayHello();    <span class="hljs-comment">//这个时候返回了一个对象给我 &#123;&#125;</span><br></code></pre></td></tr></table></figure>

<p>通过上面的代码我们可以发现，函数还是那个函数，只是我们的调有方式发生了变化，只要去通过<code>new</code>调用一个 <code>function</code>就可以构造一个对象出来</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> 对象名 = <span class="hljs-keyword">new</span> 函数();<br></code></pre></td></tr></table></figure>

<p><strong>场景</strong>：如果现在我想通过构造函数来构建我们学生的对象，应该怎么办呢，这个时候我们就要知道构造函数的<code>new</code>的运行过程，它的运行过程可以看下面的图</p>
<p><img src="https://pic.imgdb.cn/item/6123bb2e44eaada739c0865e.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210820145953900"></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//构造函数</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params"></span>) </span>&#123;<br>    <span class="hljs-comment">//this指向了新建的对象</span><br>    <span class="hljs-comment">//下面的操作就是在向新对象上面添加属性</span><br>    <span class="hljs-built_in">this</span>.name = <span class="hljs-string">&quot;陈欢欢&quot;</span>;<br>    <span class="hljs-built_in">this</span>.age = <span class="hljs-number">19</span>;<br>    <span class="hljs-built_in">this</span>.sex = <span class="hljs-string">&quot;女&quot;</span>;<br>    <span class="hljs-comment">//返回了新对象   默认返回对象</span><br>&#125;<br><br><span class="hljs-comment">//以构造函数的模式去执行Student</span><br><span class="hljs-keyword">var</span> stu1 = <span class="hljs-keyword">new</span> Student();<br></code></pre></td></tr></table></figure>

<p>现在上面的对象的属性值是固定的，我们要根据实际的数据去创建对象，这个时候我们可以把构造函数里添加参数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params">_name, _sex, _age</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.name = _name;<br>    <span class="hljs-built_in">this</span>.sex = _sex;<br>    <span class="hljs-built_in">this</span>.age = _age;<br>&#125;<br><br><span class="hljs-keyword">var</span> stu1 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;季强&quot;</span>, <span class="hljs-string">&quot;男&quot;</span>, <span class="hljs-number">19</span>);<br><span class="hljs-keyword">var</span> stu2 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;陈欢欢&quot;</span>, <span class="hljs-string">&quot;女&quot;</span>, <span class="hljs-number">20</span>);<br></code></pre></td></tr></table></figure>

<p>通过上面的代码，我们可以快速的构造我们所需要的对象了</p>
<p><strong>注意</strong>：之前的工厂模式可以帮我们快速构建格式相同的对象，但是无法区分对象的类型；现在构造函数也可以快速的构造对象了，它是否可以区分对象类型呢？</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">name, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.name = name;<br>    <span class="hljs-built_in">this</span>.sex = sex;<br>    <span class="hljs-built_in">this</span>.sayHello = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我叫&quot;</span> + <span class="hljs-built_in">this</span>.name);<br>    &#125;<br>&#125;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Dog</span>(<span class="hljs-params">name, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.name = name;<br>    <span class="hljs-built_in">this</span>.sex = sex;<br>    <span class="hljs-built_in">this</span>.sayHello = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;旺旺旺...&quot;</span>);<br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">var</span> zhangsan = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">&quot;张珊&quot;</span>, <span class="hljs-string">&quot;女&quot;</span>); <span class="hljs-comment">//构造函数创建了一个人</span><br><span class="hljs-keyword">var</span> dahuang = <span class="hljs-keyword">new</span> Dog(<span class="hljs-string">&quot;大黄&quot;</span>, <span class="hljs-string">&quot;公&quot;</span>); <span class="hljs-comment">//构造函数创建了一个狗</span><br><br><span class="hljs-built_in">console</span>.log(zhangsan <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Object</span>); <span class="hljs-comment">//true</span><br><span class="hljs-built_in">console</span>.log(dahuang <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Object</span>); <span class="hljs-comment">//true</span><br><span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;------------------&quot;</span>);<br><span class="hljs-comment">//这才是真正的区分</span><br><span class="hljs-built_in">console</span>.log(zhangsan <span class="hljs-keyword">instanceof</span> Person); <span class="hljs-comment">//true</span><br><span class="hljs-built_in">console</span>.log(dahuang <span class="hljs-keyword">instanceof</span> Dog); <span class="hljs-comment">//true</span><br><span class="hljs-built_in">console</span>.log(zhangsan <span class="hljs-keyword">instanceof</span> Dog);<span class="hljs-comment">//false</span><br><span class="hljs-built_in">console</span>.log(dahuang <span class="hljs-keyword">instanceof</span> Person);<span class="hljs-comment">//false</span><br></code></pre></td></tr></table></figure>

<img src="https://pic.imgdb.cn/item/6123baf944eaada739c02b1b.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210820152310183" style="zoom:50%;" />

<p>这个时候我们再去使用<code>instanceof</code>去检测对象类型的时候，就可以区分2个对象</p>
<h3 id="1-2构造函数与普通函数的区别"><a href="#1-2构造函数与普通函数的区别" class="headerlink" title="1.2构造函数与普通函数的区别"></a>1.2构造函数与普通函数的区别</h3><p>构造函数的定义与普通函数的定义本质上面是没有什么区别的，关键点就在于它们的调用方式</p>
<ol>
<li><p>构造函数使用的是<code>new</code>在调用，而普通函数是通过<code>函数名+()</code>来进行调用</p>
</li>
<li><p>构造函数默认返回的是创建的这个对象，而普通函数则是通过<code>return</code>关键字来返回的。<strong>如果构造函数内部返回的是一个对象类型，则会接收返回的对象类型</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">name</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.name = name;<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">123</span>;<br>&#125;<br><br><span class="hljs-keyword">var</span> a = Person(<span class="hljs-string">&quot;张三&quot;</span>); <span class="hljs-comment">//以普通函数调用，你return什么，我就返回什么</span><br><span class="hljs-keyword">var</span> b = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">&quot;李四&quot;</span>); <span class="hljs-comment">//以构造函数调用，默认返回当前创建的对象  返回的不是对象 不用管</span><br></code></pre></td></tr></table></figure>

<p>在上面的代码当中，我们的<code>return 123</code>是一个基本数据类型，所以在使用构造函数<code>new Person(&quot;李四&quot;)</code>的时候，它接的就是我们构造函数构造的对象</p>
<p>但是</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params">name</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.name = name;<br>    <span class="hljs-keyword">var</span> obj = &#123;<br>        <span class="hljs-attr">haha</span>: <span class="hljs-string">&quot;123123123&quot;</span><br>    &#125;<br>    <span class="hljs-keyword">return</span> obj;<br>&#125;<br><br><span class="hljs-keyword">var</span> c = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;王五&quot;</span>); <span class="hljs-comment">//因为构造函数内部返回的是对象类型， 所以它会接收返回的对象类型obj</span><br></code></pre></td></tr></table></figure>

<p>如果构造函数内部返回的是一个对象类型，则不再接收构造函数构造的对象，而接收<code>return</code>返回过来的对象</p>
<p><strong>构造函数并不是不接收return的返回值 ，只是如果你返回的是基本数据类型，我就不要（我就接收构造的对象），如果你返回的是一个对象类型，那我就要了返回的结果（这个时候就不再要默认返回的构造对象了）</strong></p>
</li>
<li><p>构造函数里面的<code>this</code>是指向了当前构造函数所创建的对象，而普通函数里面的<code>this</code>指向了浏览器的全局对象<code>window</code>【后面讲到<code>this</code>指针会专门讲到】</p>
</li>
<li><p>如果是通过<code>new</code>在调用构造函数并且这个时候不需要构造函数里面传递参数的时候，我们可以把构造函数小括号省略掉</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu = <span class="hljs-keyword">new</span> Student;   <span class="hljs-comment">//不传参 可以省略构造函数的括号</span><br><span class="hljs-keyword">var</span> obj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Object</span>;<br><span class="hljs-keyword">var</span> arr = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>;<br></code></pre></td></tr></table></figure>

<p>这一点就充分的说明了构造函数的调用不是依赖于后面的小括号<code>()</code>，而是通过<code>new</code>在进行调用，那个<code>()</code>的只是为了传递参数</p>
</li>
</ol>
<p><strong>题外话</strong>：构造函数的函数名一般情况下<strong>首字母要大写</strong>，这量一种命名规范，系统当中如果你发现了这个系统的首字母是大写的，那么这个函数就有可能是一个构造函数</p>
<h3 id="1-3对象调用属性"><a href="#1-3对象调用属性" class="headerlink" title="1.3对象调用属性"></a>1.3对象调用属性</h3><p>目前来说对象调用属性的方式有很多种，我们在ECMAScript5的阶段，只学习2种</p>
<h4 id="第一种调用方式"><a href="#第一种调用方式" class="headerlink" title="第一种调用方式"></a>第一种调用方式</h4><p>最常规的调用方式就是我们的<code>对象.属性名</code>来调用，如下所示</p>
<blockquote>
<p>当对象的属性名遵守的是我们之前变量命名规范来的，就可以直接通过<code>对象.属性</code>来调用</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">console</span>.log(stu1.name);<br><span class="hljs-built_in">console</span>.log(stu1.age);<br><span class="hljs-built_in">console</span>.log(stu1.sex);<br><span class="hljs-built_in">console</span>.log(stu1.hobby);<br>stu1.sayHello();			<span class="hljs-comment">//调用sayHello这个方法</span><br></code></pre></td></tr></table></figure>

<p>这一种方式的调用是最常规的调用方式，这一种方式的调用还有一小问题，有部分属性我们调用不了</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu2 = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;杨佳琪&quot;</span>,<br>    <span class="hljs-number">1</span>: <span class="hljs-string">&quot;这是一个数组的属性&quot;</span>,<br>    <span class="hljs-string">&quot;a-b&quot;</span>: <span class="hljs-string">&quot;嘿嘿，你来调我啊&quot;</span><br>&#125;;<br></code></pre></td></tr></table></figure>

<p>在上面的代码里面，我们的属性有<code>1</code>和<code>a-b</code>这两种情况，针对这两种情况，我们的如果还使用这一种<code>对象.属性名</code>的方式来调用则是不可以的</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript">stu2<span class="hljs-number">.1</span>;			<span class="hljs-comment">//这会报错</span><br>stu2.a-b		<span class="hljs-comment">//这也是会报错的</span><br></code></pre></td></tr></table></figure>

<img src="C:\Users\Administrator\Desktop\note\Untitled.assets\image-20210820104153076.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210820104153076" style="zoom:33%;" />

<p>对于上面特殊属性的调用，我们要使用第二种试来完成</p>
<h4 id="第二种调用方式"><a href="#第二种调用方式" class="headerlink" title="第二种调用方式"></a>第二种调用方式</h4><p>对于一些特殊的属性，我们可以使用<code>对象[属性名]</code>来进行调用</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu2 = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;杨佳琪&quot;</span>,<br>    <span class="hljs-number">1</span>: <span class="hljs-string">&quot;这是一个数组的属性&quot;</span>,<br>    <span class="hljs-string">&quot;a-b&quot;</span>: <span class="hljs-string">&quot;嘿嘿，你来调我啊&quot;</span><br>&#125;;<br><br><span class="hljs-built_in">console</span>.log(stu2.name);<br><span class="hljs-built_in">console</span>.log(stu2[<span class="hljs-string">&quot;name&quot;</span>]);<br><br><span class="hljs-comment">//接下来调用特殊的属性</span><br><span class="hljs-built_in">console</span>.log(stu2[<span class="hljs-number">1</span>]);  <span class="hljs-comment">//这里的1不是下标</span><br><span class="hljs-built_in">console</span>.log(stu2[<span class="hljs-string">&quot;a-b&quot;</span>]);<br><br><span class="hljs-comment">//调用方法</span><br>stu2.sayHello();<br>stu2[<span class="hljs-string">&quot;sayHello&quot;</span>]();<br><br><br><span class="hljs-keyword">var</span> arr = [<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;b&quot;</span>, <span class="hljs-string">&quot;c&quot;</span>, <span class="hljs-string">&quot;d&quot;</span>, <span class="hljs-string">&quot;e&quot;</span>];<br><span class="hljs-comment">// 索引都是属性，属性的调用应该是通过对象.属性名来完成</span><br>arr[<span class="hljs-number">0</span>];<br><span class="hljs-comment">//数组里面的索引取值赋值也是通过属性来的</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p><code>[]</code>调用属性的方式才是万能的方式，它可以调任何属性，我们之前所学习的数组它其实也是通过这个中括号在调用属性（索引）</p>
</blockquote>
<h4 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h4><ol>
<li>当对象调用一个属性的时候，如果这个属性不存在，会返回一个<code>undefined</code></li>
<li>对象的属性是可以动态扩展的</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/*</span><br><span class="hljs-comment">        &#123;&#125;相当于new Object()</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">        var a = new Object();</span><br><span class="hljs-comment">        a.sex= &quot;男&quot;;</span><br><span class="hljs-comment">        a.age = 18;</span><br><span class="hljs-comment">        a.name = &quot;张三&quot;;</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span><br>&#125;<br>obj1.sex = <span class="hljs-string">&quot;男&quot;</span>; <span class="hljs-comment">//这里不会报错，因为属性可以动态添加</span><br><br><span class="hljs-built_in">console</span>.log(obj1.age);      <span class="hljs-comment">//不会报错，只会返回一个undefined</span><br></code></pre></td></tr></table></figure>

<hr>
<h3 id="1-4delete删除属性"><a href="#1-4delete删除属性" class="headerlink" title="1.4delete删除属性"></a>1.4delete删除属性</h3><p>如果现在我们希望删除某些属性，我们可以使用<code>delete</code>这个关键字去完成，如下所示</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">delete</span> stu.age;		<span class="hljs-comment">//删除了stu对象上面的age属性</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>使用<code>delete</code>去删除这此地属性时候，我们如果得到的结果是<code>true</code>就代表这个属性删除成功了，如果得到的结果是<code>false</code>，就说明这个属性删除失败了</p>
</blockquote>
<p><strong>扩展</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr = [<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;b&quot;</span>, <span class="hljs-string">&quot;c&quot;</span>, <span class="hljs-string">&quot;d&quot;</span>, <span class="hljs-string">&quot;e&quot;</span>];   <br><span class="hljs-keyword">delete</span> arr[<span class="hljs-number">2</span>];        <span class="hljs-comment">//删除arr对象下面，属性为2的</span><br></code></pre></td></tr></table></figure>

<img src="https://pic.imgdb.cn/item/6123b4bb44eaada739b25be8.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210823092541390" style="zoom:50%;" />

<p>上图就是得到的结果，我们可以到2这个属性已经不存在，同时，我们发现这个操作没有形成沙漏效应（队列效应）</p>
<hr>
<h3 id="1-5对象特殊属性的定义"><a href="#1-5对象特殊属性的定义" class="headerlink" title="1.5对象特殊属性的定义"></a>1.5对象特殊属性的定义</h3><p>特殊属性的定义主要使用的是两个方法</p>
<ol>
<li><code>Object.defineProperty()</code>定义单个特殊属性</li>
<li><code>Object.defineProperties()</code>定义多个特殊属性</li>
</ol>
<p>通过这种方式定义的特殊属性我们主要分为2大类必属性，分别如下</p>
<ol>
<li>数据属性</li>
<li>访问器属性</li>
</ol>
<h4 id="数据属性"><a href="#数据属性" class="headerlink" title="数据属性"></a>数据属性</h4><p>数据属性的定义方式如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj = &#123;&#125;;		<span class="hljs-comment">//先定义一普通的空对象，里面没有属性</span><br><span class="hljs-comment">//现在再向里面添加一个特殊的属性</span><br><span class="hljs-built_in">Object</span>.defineProperty(obj,<span class="hljs-string">&quot;属性名&quot;</span>,&#123;<br>    <span class="hljs-comment">//这里是属性的描述信息</span><br>&#125;);<br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/6123b2fb44eaada739ae3526.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210823095031936"></p>
<p>现在我们可以通过上面的语法格式来完成我们的第一个特殊对象</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 下面定义了一个基本的对象， 里面有一个普通属性`userName`</span><br><span class="hljs-keyword">var</span> obj = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;夹心&quot;</span><br>&#125;;<br><span class="hljs-comment">//再来定义它的特殊属性</span><br><span class="hljs-built_in">Object</span>.defineProperty(obj, <span class="hljs-string">&quot;sex&quot;</span>, &#123;<br>    <span class="hljs-attr">value</span>: <span class="hljs-string">&quot;女&quot;</span>,<br>    <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>,   <span class="hljs-comment">//不能被删除</span><br>    <span class="hljs-attr">writable</span>: <span class="hljs-literal">false</span>,     <span class="hljs-comment">//不能被改变值</span><br>    <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">false</span>   <span class="hljs-comment">//不能被常规遍历方法遍历</span><br>&#125;);<br></code></pre></td></tr></table></figure>

<h4 id="访问器属性"><a href="#访问器属性" class="headerlink" title="访问器属性"></a>访问器属性</h4><p><img src="https://pic.imgdb.cn/item/6123b54a44eaada739b3a14b.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210823111504237"></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//这是一个普通的对象</span><br><span class="hljs-keyword">var</span> stu1 = &#123;<br>    <span class="hljs-attr">birthday</span>: <span class="hljs-string">&quot;1990-6-1&quot;</span><br>&#125;<br><span class="hljs-comment">//对象里同有一个生日属性birthday</span><br><span class="hljs-comment">//我们现在希望添加一个属性age,这个属性是根据birthday来自动计算</span><br><span class="hljs-built_in">Object</span>.defineProperty(stu1, <span class="hljs-string">&quot;age&quot;</span>, &#123;<br>    <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">//不可以被删除</span><br>    <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">//可以遍历</span><br>    <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-comment">//在获取这个属性值的时候自动调用</span><br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;我在调用get的方法&quot;</span>)<br>    &#125;,<br>    <span class="hljs-attr">set</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-comment">//在设置这个属性值的时候自动调用</span><br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;我在调用set的方法&quot;</span>);<br>    &#125;<br>&#125;);<br><br><span class="hljs-built_in">console</span>.log(stu1.age);      <span class="hljs-comment">//调用stu1的age这个属性，会自动的触发get这个方法</span><br><br>stu1.age = <span class="hljs-number">10</span>;              <span class="hljs-comment">//调用了stu1的age属性赋值，会自动的触发set这个方法</span><br></code></pre></td></tr></table></figure>

<blockquote>
<ol>
<li>get方法与set方法是在对这个属性取值或赋值的一瞬间自己调用</li>
<li><code>age</code>这个属性没有<code>value</code>存储具体的数据</li>
</ol>
</blockquote>
<p><strong>场景</strong>：通过访问器属性来控制属性的赋值</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//定义一个学生的对象，这个学生的对象它有姓名与年龄</span><br><span class="hljs-comment">//年龄的赋值有要求</span><br><span class="hljs-comment">//1.不能小于0，如果小于0，则默认就给0</span><br><span class="hljs-keyword">var</span> stu = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张珊&quot;</span>,<br>    <span class="hljs-attr">_age</span>: <span class="hljs-number">18</span> <span class="hljs-comment">//这是普通的属性，可以存值</span><br>&#125;<br><br><span class="hljs-built_in">Object</span>.defineProperty(stu, <span class="hljs-string">&quot;age&quot;</span>, &#123;<br>    <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>,<br>    <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">true</span>,<br>    <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-comment">//这里就是取值操作</span><br>        <span class="hljs-comment">//访问器属性本身是不存储任何数据的</span><br>        <span class="hljs-comment">//这个时候我们需要一个数据属性来存这个值</span><br>        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>._age;<br>    &#125;,<br>    <span class="hljs-attr">set</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">v</span>) </span>&#123;<br>        <span class="hljs-comment">//这个参数v就是赋进来的值</span><br>        <span class="hljs-comment">//访问器属性不存储任何数据 ，把数据主在_age上面就可以了</span><br>        <span class="hljs-comment">//判断是否小于0</span><br>        <span class="hljs-keyword">if</span> (v &lt; <span class="hljs-number">0</span>) &#123;<br>            <span class="hljs-built_in">this</span>._age = <span class="hljs-number">0</span>;<br>        &#125; <span class="hljs-keyword">else</span> &#123;<br>            <span class="hljs-built_in">this</span>._age = v;<br>        &#125;<br>    &#125;<br>&#125;)<br></code></pre></td></tr></table></figure>

<h4 id="Object-defineProperties定义特殊属性"><a href="#Object-defineProperties定义特殊属性" class="headerlink" title="Object.defineProperties定义特殊属性"></a><code>Object.defineProperties</code>定义特殊属性</h4><p><code>Object.defineProperties</code>这个方法就可以一次性定义多个特殊属性，它的语法格式如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">Object</span>.defineProperties(对象,&#123;<br>    属性名<span class="hljs-number">1</span>:&#123;<br>        <br>    &#125;,<br>    属性名<span class="hljs-number">2</span>:&#123;<br>        <br>    &#125;<br>&#125;)<br></code></pre></td></tr></table></figure>

<p>现在我们就跟据上面的语法循环来完多个特殊属性的定义</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;标哥哥&quot;</span><br>&#125;<br><br><span class="hljs-built_in">Object</span>.defineProperties(obj, &#123;<br>    <span class="hljs-comment">// 定义了一个数据属性</span><br>    <span class="hljs-attr">sex</span>: &#123;<br>        <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>,<br>        <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">true</span>,<br>        <span class="hljs-attr">value</span>: <span class="hljs-string">&quot;男&quot;</span>,<br>        <span class="hljs-attr">writable</span>: <span class="hljs-literal">false</span><br>    &#125;,<br>    <span class="hljs-attr">age</span>: &#123;<br>        <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>,<br>        <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">true</span>,<br>        <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-number">18</span>;<br>        &#125;,<br>        <span class="hljs-attr">set</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">v</span>) </span>&#123;<br>            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;标哥哥永远都是18岁，不用赋值&quot;</span>);<br>        &#125;<br>    &#125;<br>&#125;);<br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/6123b56a44eaada739b3ed1d.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210823145221368"></p>
<hr>
<h3 id="1-6获取对象属性的描述信息"><a href="#1-6获取对象属性的描述信息" class="headerlink" title="1.6获取对象属性的描述信息"></a>1.6获取对象属性的描述信息</h3><p>我们有一个方法可以获取这些属性的描述信息<code>descriptor</code>，它的语法格式如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> 描述信息对象 = <span class="hljs-built_in">Object</span>.getOwnPropertyDescriptor(对象,属性);<br></code></pre></td></tr></table></figure>

<p>现在我们就根据上面的语法格式来完成我们的案例</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;钟宇飞&quot;</span><br>&#125;<br><span class="hljs-built_in">Object</span>.defineProperties(stu1, &#123;<br>    <span class="hljs-attr">sex</span>: &#123;<br>        <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">true</span>,<br>        <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>,<br>        <span class="hljs-attr">value</span>: <span class="hljs-string">&quot;男&quot;</span>,<br>        <span class="hljs-attr">writable</span>: <span class="hljs-literal">false</span><br>    &#125;,<br>    <span class="hljs-attr">age</span>: &#123;<br>        <span class="hljs-attr">configurable</span>: <span class="hljs-literal">true</span>,<br>        <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">true</span>,<br>        <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-number">18</span>;<br>        &#125;,<br>        <span class="hljs-attr">set</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">v</span>) </span>&#123;<br>            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;永远18岁&quot;</span>);<br>        &#125;<br>    &#125;<br>&#125;);<br><br><span class="hljs-comment">//这个时候就获取了sex这个属性的描述信息</span><br><span class="hljs-keyword">var</span> sexDesc = <span class="hljs-built_in">Object</span>.getOwnPropertyDescriptor(stu1, <span class="hljs-string">&quot;sex&quot;</span>);<br><span class="hljs-comment">/*</span><br><span class="hljs-comment">    &#123;</span><br><span class="hljs-comment">        &quot;value&quot;: &quot;男&quot;,</span><br><span class="hljs-comment">        &quot;writable&quot;: false,</span><br><span class="hljs-comment">        &quot;enumerable&quot;: true,</span><br><span class="hljs-comment">        &quot;configurable&quot;: false</span><br><span class="hljs-comment">    &#125;</span><br><span class="hljs-comment">*/</span><br><br><span class="hljs-comment">//获取userName的描述信息</span><br><span class="hljs-keyword">var</span> nameDesc = <span class="hljs-built_in">Object</span>.getOwnPropertyDescriptor(stu1, <span class="hljs-string">&quot;userName&quot;</span>);<br><span class="hljs-comment">//获取age的描述信息</span><br><span class="hljs-keyword">var</span> ageDesc = <span class="hljs-built_in">Object</span>.getOwnPropertyDescriptor(stu1, <span class="hljs-string">&quot;age&quot;</span>);<br></code></pre></td></tr></table></figure>

<blockquote>
<p>所以如果在开发工作当中，当你发现某些属性不能更改或不能删除的时候，你要先想一去获取一下这个属性的描述信息看一下，看它什么不能删或更改</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">var</span> arr = [<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;b&quot;</span>, <span class="hljs-string">&quot;c&quot;</span>, <span class="hljs-string">&quot;d&quot;</span>, <span class="hljs-string">&quot;e&quot;</span>];<br><span class="hljs-comment">//数组里面有个属性叫length,请问，length这个属性是否可以被delete删除</span><br><br><span class="hljs-comment">// delete arr.length;</span><br><span class="hljs-comment">//我也不知道是否可以，所以我要看一下这个属性的描述信息</span><br><br><span class="hljs-keyword">var</span> lengthDesc = Object.getOwnPropertyDescriptor(arr, <span class="hljs-string">&quot;length&quot;</span>);<br><span class="hljs-comment">/*</span><br><span class="hljs-comment">        length的描述信息</span><br><span class="hljs-comment">        &#123;</span><br><span class="hljs-comment">            &quot;value&quot;: 5,</span><br><span class="hljs-comment">            &quot;writable&quot;: true,</span><br><span class="hljs-comment">            &quot;enumerable&quot;: false,</span><br><span class="hljs-comment">            &quot;configurable&quot;: false   //不能删除</span><br><span class="hljs-comment">        &#125;</span><br><span class="hljs-comment">*/</span><br></code></pre></td></tr></table></figure>

<p>上面的代码就充分说明了length属性为什么不能被删除</p>
<h3 id="1-7构造函数与特殊属性的结合"><a href="#1-7构造函数与特殊属性的结合" class="headerlink" title="1.7构造函数与特殊属性的结合"></a>1.7构造函数与特殊属性的结合</h3><p>构造函数可以帮我们快速的去构造对象，而特殊属性是需要通过<code>Object.defineProperty</code>来完成的。如果我们希望通过函数创建的属性有一些是特殊属性，有如下办法实现</p>
<p><strong>案例</strong>：现在希望通过构造函数快速的去创建学生的对象，然后这学生的对象具备 <code>userName,sex,age,birthday</code>这四个属性，其中<code>sex</code>的属性一旦设置以后就不可更改，<code>age</code>是一个访问性的属性，需要通过<code>birthday</code>来决定它的年龄，<code>birthday</code>这个属性也是在旦固定以后就不能更改。</p>
<p>首先要完成上面的问题，我们先要了解构造函数。构造函数在执行的时候，有几个步骤</p>
<ol>
<li>构造函数的内部创建一个新的对象</li>
<li><code>this</code>指向了这个新的对象</li>
<li>构造函数返回了这个新创建的的对象</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//先不要考虑特殊属性，我们先只考虑构造函数的情况</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params">_userName, _sex, _birthday</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.userName = _userName;<br>    <span class="hljs-comment">//this指向了当前对象，我就在当前对象this上面去扩展属性</span><br>    <span class="hljs-built_in">Object</span>.defineProperties(<span class="hljs-built_in">this</span>, &#123;<br>        <span class="hljs-attr">sex</span>: &#123;<br>            <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>,<br>            <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">true</span>,<br>            <span class="hljs-attr">value</span>: _sex,<br>            <span class="hljs-attr">writable</span>: <span class="hljs-literal">false</span><br>        &#125;,<br>        <span class="hljs-attr">birthday</span>: &#123;<br>            <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>,<br>            <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">true</span>,<br>            <span class="hljs-attr">value</span>: _birthday,<br>            <span class="hljs-attr">writable</span>: <span class="hljs-literal">false</span><br>        &#125;,<br>        <span class="hljs-comment">//age它是一个访问器属性，这个属性的结果依赖于birthday来决定</span><br>        <span class="hljs-attr">age</span>: &#123;<br>            <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>,<br>            <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">true</span>,<br>            <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>                <span class="hljs-keyword">var</span> now = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(); <span class="hljs-comment">//当前时间</span><br>                <span class="hljs-keyword">var</span> birthdayDate = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-built_in">this</span>.birthday); <span class="hljs-comment">//出生年月的时间</span><br>                <span class="hljs-comment">//将两个时间相减</span><br>                <span class="hljs-keyword">var</span> totalTime = now - birthdayDate; <span class="hljs-comment">//680372984107  这个东西代表毫秒</span><br>                <span class="hljs-comment">//把上面的毫秒转换成年</span><br>                <span class="hljs-keyword">var</span> yearCount = <span class="hljs-built_in">parseInt</span>(totalTime / <span class="hljs-number">1000</span> / <span class="hljs-number">60</span> / <span class="hljs-number">60</span> / <span class="hljs-number">24</span> / <span class="hljs-number">365</span>);<br>                <span class="hljs-keyword">return</span> yearCount;<br>            &#125;<br>            <span class="hljs-comment">// 年龄只能获取 ，不能设置，所以只在get没有set</span><br>        &#125;<br>    &#125;);<br>&#125;<br><br><span class="hljs-keyword">var</span> s1 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;钟宇飞&quot;</span>, <span class="hljs-string">&quot;男&quot;</span>, <span class="hljs-string">&quot;1990-2-1&quot;</span>);<br><span class="hljs-keyword">var</span> s2 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;杨佳琪&quot;</span>, <span class="hljs-string">&quot;女&quot;</span>, <span class="hljs-string">&quot;2000-6-1&quot;</span>);<br></code></pre></td></tr></table></figure>

<blockquote>
<p><strong>代码分析</strong>：</p>
<ol>
<li>我们已经将构造函数与特殊属性进行了结合</li>
<li>上面的方式场景会经常看到，我们经常需要通过构造函数来构造我们的对象，同时又要设置这个对象的特殊属性</li>
</ol>
</blockquote>
<h3 id="1-8变量名做为属性名"><a href="#1-8变量名做为属性名" class="headerlink" title="1.8变量名做为属性名"></a>1.8变量名做为属性名</h3><p>一般情况下，我们在定义对象的属性的时候是通过数字或字符串来做为属性名的，但是有时候也会存在一个变量名做为属性名的情况，如下所示</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> a = <span class="hljs-string">&quot;age&quot;</span>;<br><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>    <span class="hljs-comment">//这个时候的a就仅仅只是一个属性名，不是变量名</span><br>    <span class="hljs-attr">a</span>: <span class="hljs-number">19</span><br>&#125;<br><span class="hljs-comment">//如果现在希望得到的是变量名，怎么办呢？</span><br><span class="hljs-keyword">var</span> obj2 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;李四&quot;</span>,<br>    <span class="hljs-comment">//这里的中括号代表里面的是一个变量，它不是数组</span><br>    [a]: <span class="hljs-number">22</span><br>&#125;<br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/6123b84744eaada739bada6e.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210823100857174"></p>
<p>所以请注意，如果变量名要做为属性名，这个时候我们就要使用中括号<code>[]</code>来把这个变量括起来</p>
<h3 id="1-9对象的遍历"><a href="#1-9对象的遍历" class="headerlink" title="1.9对象的遍历"></a>1.9对象的遍历</h3><h4 id="for…in遍历对象"><a href="#for…in遍历对象" class="headerlink" title="for…in遍历对象"></a>for…in遍历对象</h4><p><img src="https://pic.imgdb.cn/item/6123b51144eaada739b32208.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210823095623327"></p>
<p><img src="https://pic.imgdb.cn/item/6123b51d44eaada739b33b51.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210823095841164"></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;杨佳琪&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;女&quot;</span>,<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">18</span><br>&#125;<br><br><span class="hljs-comment">//我们现在希望把上面对象所有的属性值都拿出来 ，打印一次，怎么办呢？</span><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> stu) &#123;<br>    <span class="hljs-comment">//这里的i代表的就是我们遍历出来的每一个属性名，有了这个属性名，我们就可以得到属性值</span><br>    <span class="hljs-comment">// 对象调用属性应该是 对象.属性名</span><br>    <span class="hljs-comment">//但是现在是一个变量为做属性名，所以我们就不能使用.来调用，要使用另一种特殊方式调用</span><br>    <span class="hljs-comment">//对象[变量名]</span><br>    <span class="hljs-built_in">console</span>.log(i, stu[i]);<br>    <span class="hljs-comment">//这就代表stu调用了i这个属性，而i又是一个变量，所以相当于stu[&quot;userName&quot;],stu[&quot;sex&quot;]等</span><br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="通过Object-keys-遍历对象"><a href="#通过Object-keys-遍历对象" class="headerlink" title="通过Object.keys()遍历对象"></a>通过<code>Object.keys()</code>遍历对象</h4><p>在JavaScript的内部，我们有一个方法叫<code>Object.keys()</code>，这一个方法可以获取到某一个对象内部<code>enumerable:true</code>的属性名</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//在这里定义了一个对象，里面有2个普通的属性</span><br><span class="hljs-keyword">var</span> obj = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张珊&quot;</span>,<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">18</span><br>&#125;<br><span class="hljs-comment">//又去定义一个特殊的属性</span><br><span class="hljs-built_in">Object</span>.defineProperty(obj, <span class="hljs-string">&quot;sex&quot;</span>, &#123;<br>    <span class="hljs-attr">value</span>: <span class="hljs-string">&quot;女&quot;</span>,<br>    <span class="hljs-attr">writable</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">//不允许更改</span><br>    <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">//不允许删除</span><br>    <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">false</span> <span class="hljs-comment">//不可遍历</span><br>&#125;);<br><span class="hljs-keyword">var</span> arr = <span class="hljs-built_in">Object</span>.keys(obj);<br><span class="hljs-comment">// 这个arr里面放的就是所有enumerable:true的属性名</span><br><span class="hljs-comment">//遍历上面的属性数组，再通过属性来找属性值</span><br>arr.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">item, index, _arr</span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(item, obj[item]);<br>&#125;);<br></code></pre></td></tr></table></figure>

<p><code>Object.keys(对象)</code>它会把对象里面所有<code>enumerable:true</code> 属性拿出来构成一个数组，然后我们再遍历这个数组就相当于遍历了这个对象所有的属性</p>
<p><strong>注意</strong>：上面的2种方式都只能够遍历 <code>enumerable:true</code> 的属性</p>
<p><strong>问题</strong>：现在有没有一种方式可以把<code>enumerable:fales</code>这样的属性遍历出来呢？【遍历所有的属性】</p>
<h4 id="通过Object-getOwnPropertyNames-遍历"><a href="#通过Object-getOwnPropertyNames-遍历" class="headerlink" title="通过Object.getOwnPropertyNames()遍历"></a>通过<code>Object.getOwnPropertyNames()</code>遍历</h4><p>通过个方法可以获取到某一个对象自身上面所有的属性名，它会忽略掉<code>enumerable</code>这个特性</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//在这里定义了一个对象，里面有2个普通的属性</span><br><span class="hljs-keyword">var</span> obj = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张珊&quot;</span>,<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">18</span><br>&#125;<br><span class="hljs-comment">//又去定义一个特殊的属性</span><br><span class="hljs-built_in">Object</span>.defineProperty(obj, <span class="hljs-string">&quot;sex&quot;</span>, &#123;<br>    <span class="hljs-attr">value</span>: <span class="hljs-string">&quot;女&quot;</span>,<br>    <span class="hljs-attr">writable</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">//不允许更改</span><br>    <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">//不允许删除</span><br>    <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">false</span> <span class="hljs-comment">//不可遍历</span><br>&#125;);<br><span class="hljs-comment">// 这个时候会得到obj对象自身所有的属性名</span><br><span class="hljs-keyword">var</span> arr = <span class="hljs-built_in">Object</span>.getOwnPropertyNames(obj);			<span class="hljs-comment">//[&quot;userName&quot;,&quot;age&quot;,&quot;sex&quot;]</span><br>arr.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">item, index, _arr</span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(item,obj[item]);<br>&#125;);<br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/6123b9db44eaada739be3099.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210823110753776"></p>
<h3 id="1-10判断对象是否具备某一个属性"><a href="#1-10判断对象是否具备某一个属性" class="headerlink" title="1.10判断对象是否具备某一个属性"></a>1.10判断对象是否具备某一个属性</h3><p>假设现在一个对象，我们需要判断这个对象是否具备某一个属性，怎么办呢？</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu = &#123;<br>    <span class="hljs-attr">userName</span>:<span class="hljs-string">&quot;钟宇飞&quot;</span>,<br>    <span class="hljs-attr">sex</span>:<span class="hljs-string">&quot;男&quot;</span><br>&#125;<br><span class="hljs-built_in">Object</span>.defineProperty(stu,<span class="hljs-string">&quot;age&quot;</span>,&#123;<br>    <span class="hljs-attr">configurable</span>:<span class="hljs-literal">false</span>,<br>    <span class="hljs-attr">enumerable</span>:<span class="hljs-literal">false</span>,<br>    <span class="hljs-attr">value</span>:<span class="hljs-number">18</span>,<br>    <span class="hljs-attr">writable</span>:<span class="hljs-literal">false</span><br>&#125;);<br></code></pre></td></tr></table></figure>

<p>现在就有上面这个对象，我们想判断这个对象是否具备某一个属性，怎么判断呢？</p>
<p>面对上面的问题的时候，很多同学可能会想我们要使用我们的对象遍历来完成，但是这样做有一个小小的隐患，之前所学习的<code>for...in</code>与<code>Object.keys()</code>都只能遍历<code>enumerable:ture</code>的，所以我们判断对象是否具备某一个属性的时候不能使用这2个方法，要使用另外的方法</p>
<h4 id="第一种方法"><a href="#第一种方法" class="headerlink" title="第一种方法"></a>第一种方法</h4><p>这一种方法借助于的是我们的<code>Object.getOwnPropertyNames</code>这个函数来完成的，它可以获取到对象里面所有的属性名，把所有的属名放在一个数组里面，然后我们再通过数组的<code>indexOf</code>这个方法去查找即可</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr = <span class="hljs-built_in">Object</span>.getOwnPropertyNames(stu);<br><span class="hljs-comment">// arr就是当前这个对象stu所有的属性名</span><br><span class="hljs-comment">// 接下来只要判断数组里面是否具备某一个元素就可以了</span><br><span class="hljs-keyword">if</span> (arr.indexOf(<span class="hljs-string">&quot;userName&quot;</span>) != -<span class="hljs-number">1</span>) &#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;userName属性存在&quot;</span>);<br>&#125; <span class="hljs-keyword">else</span> &#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;userName属性不存在&quot;</span>);<br>&#125;<br><span class="hljs-keyword">if</span>(arr.indexOf(<span class="hljs-string">&quot;sex&quot;</span>)!=-<span class="hljs-number">1</span>)&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;sex属性存在&quot;</span>);<br>&#125;<br><span class="hljs-keyword">else</span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;sex属性不存在&quot;</span>);<br>&#125;<br><span class="hljs-keyword">if</span> (arr.indexOf(<span class="hljs-string">&quot;age&quot;</span>) != -<span class="hljs-number">1</span>) &#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;age属性存在&quot;</span>);<br>&#125; <span class="hljs-keyword">else</span> &#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;age属性不存在&quot;</span>);<br>&#125;<br></code></pre></td></tr></table></figure>

<blockquote>
<p>这一个方法比较麻烦，一般用得很少，标哥也不推荐这个方法</p>
</blockquote>
<h4 id="第二种方法"><a href="#第二种方法" class="headerlink" title="第二种方法"></a>第二种方法</h4><p>判断某一个对象是否具备某一个属性在后来的时候出了一个新的关键字，这个关键字叫<code>in</code>，它的语法格式如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">属性 <span class="hljs-keyword">in</span> 对象;	<br></code></pre></td></tr></table></figure>

<p>如果上面的结果返回为<code>true</code>则代表对象具备个属性，如果结果返回<code>false</code>则代表对象不具备这个属性</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-string">&quot;userName&quot;</span> <span class="hljs-keyword">in</span> stu; <span class="hljs-comment">//true</span><br><span class="hljs-string">&quot;sex&quot;</span> <span class="hljs-keyword">in</span> stu; <span class="hljs-comment">//true</span><br><span class="hljs-string">&quot;age&quot;</span> <span class="hljs-keyword">in</span> stu; <span class="hljs-comment">//true</span><br><br><span class="hljs-string">&quot;birthday&quot;</span> <span class="hljs-keyword">in</span> stu;  <span class="hljs-comment">//false;</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p><strong>代码分析</strong>：</p>
<ol>
<li><code>in</code>去检测的时候如果对象具备这个属性就是<code>true</code> ,否则就是<code>false</code></li>
<li><code>in</code>的检测会去到父级对象上面去检测【后面讲对象的继承会提到这里】</li>
<li>标哥后期会经使用这个方法来判断对象是否具备属性【首选方案】</li>
</ol>
</blockquote>
<h4 id="第三种方法"><a href="#第三种方法" class="headerlink" title="第三种方法"></a>第三种方法</h4><p>在我们对象的内部有一个方法用于判断这个对象是否具备某一个属性， 这个方法叫<code>hasOwnProperty() </code>,这个方法如果返回的结果是<code>true</code>则代表具备这个属性，如果是<code>false</code>就代表没有这个属性</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript">stu.hasOwnProperty(<span class="hljs-string">&quot;userName&quot;</span>);     <span class="hljs-comment">//true</span><br>stu.hasOwnProperty(<span class="hljs-string">&quot;sex&quot;</span>);          <span class="hljs-comment">//true</span><br>stu.hasOwnProperty(<span class="hljs-string">&quot;age&quot;</span>);          <span class="hljs-comment">//true</span><br><br>stu.hasOwnProperty(<span class="hljs-string">&quot;aaaa&quot;</span>);         <span class="hljs-comment">//false</span><br></code></pre></td></tr></table></figure>

<p><span style="color:red;text-decoration:underline wavy blue;font-weight:bold">对象是否具备某一个属性我们应该忽略掉<code>enumerable</code>这个特性，因为这个特性只是用于控制遍历的，并不是用来控制是否存在的</span></p>
<p><img src="https://pic.imgdb.cn/item/6123ba8744eaada739bf641c.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210823171106054"></p>
<hr>
<h2 id="2-对象的继承关系"><a href="#2-对象的继承关系" class="headerlink" title="2.对象的继承关系"></a>2.对象的继承关系</h2><blockquote>
<p>提一点：在JS里面，所有对象的父级最终都会继承自<code>Object</code></p>
</blockquote>
<h3 id="2-1通过call-apply去实现继承"><a href="#2-1通过call-apply去实现继承" class="headerlink" title="2.1通过call/apply去实现继承"></a>2.1通过<code>call/apply</code>去实现继承</h3><p>在我们的JavaScrit里面，继承的方式多种多样，现在<code>call/apply</code>的继承是一种最简单的方式，也是最直观的方式</p>
<pre><code class=" mermaid">graph TD
A[Person人]--&gt;|继承|B[Student学生]
A--&gt;|继承|C[Teacher老师]
</code></pre>

<p>我们现在需要按照上图所示的思路来完成，先提取公共的部分去形成一个<code>Person</code>的人的对象，然后再让新的<code>Student</code>与<code>Teacher</code>构造函数实现继承</p>
<p><strong>继承</strong>：上图里面使用到一个关键字继承。继承是对象之间的关系，当一个子级元素继承了父级元素以后，子级元素就可以使用父级元素的属性与方法了</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 我们将两个对象公共的部分单独提取出来了</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.userName = userName;<br>    <span class="hljs-built_in">this</span>.sex = sex;<br>    <span class="hljs-built_in">this</span>.sayHello = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我叫&quot;</span> + <span class="hljs-built_in">this</span>.userName);<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">//定义学生对象</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params">sno, userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.sno = sno;<br>    <span class="hljs-comment">//Student是以构造函数运行的，所以this指向了当前新创建的对象</span><br>    Person.call(<span class="hljs-built_in">this</span>, userName, sex); <span class="hljs-comment">//调用了Person的方法，并且把Person里面的this指向了Student创建的对象</span><br>&#125;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Teacher</span>(<span class="hljs-params">tid, userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.tid = tid;<br>    Person.call(<span class="hljs-built_in">this</span>, userName, sex);<br>&#125;<br><br><span class="hljs-keyword">var</span> s1 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;H21030001&quot;</span>, <span class="hljs-string">&quot;高远航&quot;</span>, <span class="hljs-string">&quot;男&quot;</span>);<br><span class="hljs-keyword">var</span> t1 = <span class="hljs-keyword">new</span> Teacher(<span class="hljs-string">&quot;10000040&quot;</span>,<span class="hljs-string">&quot;标哥哥&quot;</span>,<span class="hljs-string">&quot;男&quot;</span>);<br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/6124fe3144eaada739f1b34a.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210824101538150"></p>
<p><strong>同时我们可以将上面的<code>call</code>的方式写成<code>apply</code>的方式</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 我们将两个对象公共的部分单独提取出来了</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.userName = userName;<br>    <span class="hljs-built_in">this</span>.sex = sex;<br>    <span class="hljs-built_in">this</span>.sayHello = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我叫&quot;</span> + <span class="hljs-built_in">this</span>.userName);<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">//编写一个学生对象</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params">sid, userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.sid = sid;<br>    <span class="hljs-comment">// Person.call(this,userName,sex);</span><br>    <span class="hljs-comment">// 上面是通过call来完成，现在我们可以通过apply去完成</span><br>    Person.apply(<span class="hljs-built_in">this</span>, [userName, sex]);       <span class="hljs-comment">//apply的参数 为数组</span><br>&#125;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Teacher</span>(<span class="hljs-params">tid, userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.tid = tid;<br>    Person.apply(<span class="hljs-built_in">this</span>, [userName, sex]);<br>&#125;<br><span class="hljs-keyword">var</span> s1 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;H21030001&quot;</span>, <span class="hljs-string">&quot;高远航&quot;</span>, <span class="hljs-string">&quot;男&quot;</span>);<br><span class="hljs-keyword">var</span> t1 = <span class="hljs-keyword">new</span> Teacher(<span class="hljs-string">&quot;10000040&quot;</span>, <span class="hljs-string">&quot;标哥&quot;</span>, <span class="hljs-string">&quot;男&quot;</span>);<br></code></pre></td></tr></table></figure>

<p><span style="color:red;font-size:22px;"><strong>存在的问题</strong>：</span></p>
<p>我们通过上面的方式已经可以实现了对象之前的继承关系，但是它们有一个致使的缺点，如下图所示</p>
<p><img src="https://pic.imgdb.cn/item/6125008344eaada739f6b404.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210824110709459"></p>
<p>通过上面的图，我们发现了一个很明显的问题，<strong>我们从当前对象上面根本就看不到哪些是父级对象的属性，哪些是子级对象的属性</strong>。通过这种方式实现的继承它把所有的属性都放在子级对象上面，并没有严格的构成我们父子关系，只是将所有的属性进行了混合</p>
<h3 id="2-2通过原型来实现继承"><a href="#2-2通过原型来实现继承" class="headerlink" title="2.2通过原型来实现继承"></a>2.2通过原型来实现继承</h3><p>要弄清楚这一点就必须要知道什么是“原型”</p>
<h4 id="理解原型"><a href="#理解原型" class="headerlink" title="理解原型"></a>理解原型</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params">userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.userName = userName;<br>    <span class="hljs-built_in">this</span>.sex = sex;<br>&#125;<br><span class="hljs-keyword">var</span> s1 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;张珊&quot;</span>, <span class="hljs-string">&quot;女&quot;</span>);<br><br><span class="hljs-comment">//s1是当前构造函数Student所构造出来的对象</span><br>s1 <span class="hljs-keyword">instanceof</span> Student;      <span class="hljs-comment">//true</span><br></code></pre></td></tr></table></figure>

<p>上面就是一个构造函数构造出了一个对象，我们昨天也学到了另一个点，如果想判断某一个对象是否具备某一个属性，我们可以使用<code>in</code>这个关键字</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-string">&quot;userName&quot;</span> <span class="hljs-keyword">in</span> s1;       <span class="hljs-comment">//true</span><br><span class="hljs-string">&quot;sex&quot;</span> <span class="hljs-keyword">in</span> s1;            <span class="hljs-comment">//true</span><br><span class="hljs-string">&quot;aaa&quot;</span> <span class="hljs-keyword">in</span> s1;            <span class="hljs-comment">//false</span><br><span class="hljs-string">&quot;toString&quot;</span> <span class="hljs-keyword">in</span> s1;       <span class="hljs-comment">//true</span><br></code></pre></td></tr></table></figure>

<p>在上面的代码当中，我们对一些属性进行了检测，我们可以看到<code>toString</code>在去做检测的时候得到的结果是<code>true</code>，这是为什么呢？我看来截图</p>
<p><img src="https://pic.imgdb.cn/item/6125039444eaada739fee0ed.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210824111734935"></p>
<p>上图当中，我们看到s1这个对象上面根本就没有<code>toString</code>，所以这个属性肯定不是属于<code>s1</code>的，但是它检测出来的结果又是<code>true</code>，而<code>in</code>的检测又是可以检测到父级的，所以我们猜测，<code>toString</code>可能是它父级的属性</p>
<p>在上面中，我们可以看到，<code>s1</code>除了有<code>sex,userName</code>这两个属性以外，还有一个<code>Prototype</code>这个属性（这个属性以前叫<code>__proto__</code>）,它就是当前<code>s1</code>这个对象的原型，<strong>而原型在JS里面也叫父级对象</strong></p>
<img src="https://pic.imgdb.cn/item/612503be44eaada739ff5e87.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210824112338926" style="zoom:50%;" />

<p>这个时候我们在父级上面找到了<code>toString</code>这个属性，所以在<code>toString in s1</code>的时候得到的结果就是<code>true</code></p>
<p>所以根据上面的要求，我们如果想让a对象继承b对象，这个时候只要把a对象的原型设置为b就可以了</p>
<p>通过上面的例子，我们已经知道，所谓的原型其实指的就是父级对象，也就是当前对象上面的<code>对象.__proto__</code>这个东西</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr = [<span class="hljs-string">&quot;hello&quot;</span>,<span class="hljs-string">&quot;方华升&quot;</span>,<span class="hljs-string">&quot;郭磊磊&quot;</span>];<br>arr.push===arr.__proto__.push;			<span class="hljs-comment">//arr本身没有push这个属性方法，它调用是原型（父级）上面的方法</span><br></code></pre></td></tr></table></figure>

<h4 id="原型方式的继承"><a href="#原型方式的继承" class="headerlink" title="原型方式的继承"></a>原型方式的继承</h4><p>原型方式的继承有很多种情况，也有很多种写法，我们在这里介绍主流的2种写法</p>
<p><strong>第一种，简单方式的原型继承</strong>【基础】</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> p1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;男&quot;</span>,<br>    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我叫&quot;</span> + <span class="hljs-built_in">this</span>.userName);<br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">var</span> s1 = &#123;<br>    <span class="hljs-attr">sid</span>: <span class="hljs-string">&quot;H21030001&quot;</span><br>&#125;<br><br><span class="hljs-comment">//想让s1继承自p1</span><br><span class="hljs-comment">//这个时候只要把s1原型设置为p1这个对象就可以</span><br><span class="hljs-comment">//这个时候就开始认爹了</span><br>s1.__proto__ = p1;<br></code></pre></td></tr></table></figure>

<p>通过浏览器，我们可以看到它们的层级关系</p>
<img src="https://pic.imgdb.cn/item/6125042744eaada739007b98.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210824113658813" style="zoom:50%;" />

<p>这一种方式只是一种最简单的方式，如果我们需要批量创建对象的时候，这个做就不好了</p>
<p><strong>第二种，通过构造函数来实现原型继承</strong>【过渡，不建议使用】</p>
<p>这一种方式是一个很普遍的方式，如果我们希望批量的设置父级的时候，我们应付地这么做</p>
<p><strong>场景</strong>：现在有一个构造函数，我们希望这个构造函数所创建的对象都有一个父级，这个父级就是另一个对象，怎么办呢？</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 这里定义了一个构造函数</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params">userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.userName = userName;<br>    <span class="hljs-built_in">this</span>.sex = sex;<br>&#125;<br><br><span class="hljs-comment">//这里就建了一个对象father</span><br><span class="hljs-keyword">var</span> father = &#123;<br>    <span class="hljs-attr">myName</span>: <span class="hljs-string">&quot;张爹爹&quot;</span>,<br>    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;我叫&quot;</span> + <span class="hljs-built_in">this</span>.myName);<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">//到这一步，我们就可以通过构造函数来创建对象了</span><br><span class="hljs-comment">//现在我们需要所有构造出来的学生的爹都是father怎么办呢</span><br><span class="hljs-keyword">var</span> s1 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;张珊&quot;</span>, <span class="hljs-string">&quot;女&quot;</span>);<br><span class="hljs-keyword">var</span> s2 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;张四&quot;</span>, <span class="hljs-string">&quot;男&quot;</span>);<br><br><span class="hljs-comment">//现在我们要一个一个的去设置</span><br><span class="hljs-comment">//设置s1的原型</span><br>s1.__proto__ = father;<br><span class="hljs-comment">//设置s2的原型</span><br>s2.__proto__ = father;<br></code></pre></td></tr></table></figure>

<p>这一种模式其实也是存在的，但是这么做就有一个不好的地方，我们每个对象在创建以后，都要手动的去设置它的原型<code>__proto__</code>，这样就很麻烦</p>
<p><span style="color:red;font-size:26px;font-weight:bold;">在JS的对象里面，一个对象的<code>__proto__</code>应该等于这个对象的构造函数的<code>prototype</code>属性</span></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 这里定义了一个构造函数</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params">userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.userName = userName;<br>    <span class="hljs-built_in">this</span>.sex = sex;<br>&#125;<br><br><span class="hljs-comment">//这里就建了一个对象father</span><br><span class="hljs-keyword">var</span> father = &#123;<br>    <span class="hljs-attr">myName</span>: <span class="hljs-string">&quot;张爹爹&quot;</span>,<br>    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;我叫&quot;</span> + <span class="hljs-built_in">this</span>.myName);<br>    &#125;<br>&#125;<br><span class="hljs-comment">//s1是当前这个对象，这个对象的构造函数是Student</span><br><span class="hljs-comment">//对象的__proto__应该等于它的构造函数的prototype</span><br><span class="hljs-keyword">var</span> s1 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;张珊&quot;</span>, <span class="hljs-string">&quot;女&quot;</span>);<br>s1.__proto__ === Student.prototype; <span class="hljs-comment">//true</span><br><br><span class="hljs-comment">//现在只用设置这一个就可以了</span><br>Student.prototype = father;<br><br><span class="hljs-keyword">var</span> s2 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;张四&quot;</span>, <span class="hljs-string">&quot;男&quot;</span>);<br></code></pre></td></tr></table></figure>

<blockquote>
<p>上面的代码当中，关键的一点就是在于一个对象的<code>__proto__</code>应该是等于它的构造函数的<code>prototype</code>的。</p>
</blockquote>
<p><strong>第三种方式</strong>：这一种方式是在第二种方式的基础上面进行了改版【过渡】</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params"></span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.sayHello = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我叫&quot;</span> + <span class="hljs-built_in">this</span>.userName);<br>    &#125;<br>&#125;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params">sid, userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.sid = sid;<br>    <span class="hljs-built_in">this</span>.userName = userName;<br>    <span class="hljs-built_in">this</span>.sex = sex;<br>&#125;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Teacher</span>(<span class="hljs-params">tid,userName,sex</span>)</span>&#123;<br>    <span class="hljs-built_in">this</span>.tid = tid;<br>    <span class="hljs-built_in">this</span>.userName = userName;<br>    <span class="hljs-built_in">this</span>.sex = sex;<br>&#125;<br><br><span class="hljs-comment">//现在两个东西都是构造函数 ，怎么实现继承了【重点】</span><br>Student.prototype = <span class="hljs-keyword">new</span> Person();<br>Teacher.prototype = <span class="hljs-keyword">new</span> Person();<br><br><span class="hljs-keyword">var</span> s1 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;1001&quot;</span>,<span class="hljs-string">&quot;张三&quot;</span>,<span class="hljs-string">&quot;男&quot;</span>);<br><span class="hljs-keyword">var</span> s2 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;1002&quot;</span>,<span class="hljs-string">&quot;西施&quot;</span>,<span class="hljs-string">&quot;女&quot;</span>);<br><br><span class="hljs-keyword">var</span> t1 = <span class="hljs-keyword">new</span> Teacher(<span class="hljs-string">&quot;10000040&quot;</span>,<span class="hljs-string">&quot;标哥&quot;</span>,<span class="hljs-string">&quot;男&quot;</span>);<br></code></pre></td></tr></table></figure>

<blockquote>
<p>在上面的代码当中，虽然我们实现了预期的效果，但是，我们发现有一些公共代码，我们没有提取出来，只是提取了方法<code>sayHello</code></p>
</blockquote>
<h5 id="第四种方法：这是ECMAScript5里面的终级办法"><a href="#第四种方法：这是ECMAScript5里面的终级办法" class="headerlink" title="第四种方法：这是ECMAScript5里面的终级办法"></a><strong>第四种方法</strong>：这是ECMAScript5里面的终级办法</h5><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">userName, sex</span>) </span>&#123;<br>     <span class="hljs-built_in">this</span>.userName = userName;<br>     <span class="hljs-built_in">this</span>.sex = sex;<br>     <span class="hljs-built_in">this</span>.sayHello = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>         <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我叫&quot;</span> + <span class="hljs-built_in">this</span>.userName);<br>     &#125;<br> &#125;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Student</span>(<span class="hljs-params">sid, userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.sid = sid;<br>    <span class="hljs-comment">//继承Person</span><br>    <span class="hljs-comment">//this就是指代当前对象</span><br>    <span class="hljs-built_in">this</span>.__proto__ = <span class="hljs-keyword">new</span> Person(userName, sex);<br><br>&#125;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Teacher</span>(<span class="hljs-params">tid, userName, sex</span>) </span>&#123;<br>    <span class="hljs-built_in">this</span>.tid = tid;<br>    <span class="hljs-comment">// 继承Person</span><br>    <span class="hljs-built_in">this</span>.__proto__ = <span class="hljs-keyword">new</span> Person(userName, sex);<br>&#125;<br><br><span class="hljs-comment">//一个对象的__proto__应该等于这个对象构造函数的prototype</span><br><br><span class="hljs-keyword">var</span> s1 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">&quot;1001&quot;</span>, <span class="hljs-string">&quot;张珊&quot;</span>, <span class="hljs-string">&quot;女&quot;</span>);<br><span class="hljs-keyword">var</span> t1 = <span class="hljs-keyword">new</span> Teacher(<span class="hljs-string">&quot;t01&quot;</span>, <span class="hljs-string">&quot;标哥哥&quot;</span>, <span class="hljs-string">&quot;男&quot;</span>);<br></code></pre></td></tr></table></figure>

<img src="C:\Users\Administrator\Desktop\note\JavaScript面向对象（三）.assets\image-20210824145815631.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210824145815631" style="zoom:50%;" />



<p>在上面的通过原型继承的方式里面，我们可以很容易就形成层关系，其中上面的4个方法，通俗一点来说其实就是4个步骤 ，我们只用记最后一个步骤就行了。同时再去一句话“一个对象的<code>__proto__</code>应该是等于它的构造函数的<code>prototype</code>的”</p>
<h3 id="2-3对象的包含关系"><a href="#2-3对象的包含关系" class="headerlink" title="2.3对象的包含关系"></a>2.3对象的包含关系</h3><p>对象的包含主要指的是一个对象包含另一个对象，例如学生对象是属于我们的班级对象的，这是一个非常简单的东西，我们一带而过。</p>
<p><strong>场景</strong>：假设有一个学生有2个手机，可以用对象数组表示</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;钟宇飞&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;男&quot;</span>,<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">19</span>,<br>    <span class="hljs-attr">address</span>: <span class="hljs-string">&quot;湖北省武汉市&quot;</span>,<br>    <span class="hljs-attr">telphone</span>: [&#123;      <span class="hljs-comment">//对象数组</span><br>        <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;小米11&quot;</span>,<br>        <span class="hljs-attr">price</span>: <span class="hljs-number">9999</span>,<br>        <span class="hljs-attr">battery</span>: <span class="hljs-number">4300</span><br><br>    &#125;, &#123;<br>        <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;菲尔普斯山寨机&quot;</span>,<br>        <span class="hljs-attr">price</span>: <span class="hljs-number">1999</span>,<br>        <span class="hljs-attr">battery</span>: <span class="hljs-number">2000</span><br>    &#125;]<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="补充"><a href="#补充" class="headerlink" title="补充!!!"></a>补充!!!</h3><p>在之前我们已经讲过了方法的调用方式，在JS里在，函数的调有和是有很多种方式</p>
<ol>
<li><code>函数名()</code>这种方式来调用</li>
<li><code>new 函数名()</code>来调用</li>
</ol>
<p>其实在上面的两种试以外，我们还2种其它的调用方式</p>
<h4 id="通过call来调用函数"><a href="#通过call来调用函数" class="headerlink" title="通过call来调用函数"></a>通过<code>call</code>来调用函数</h4><p>这一种是函数最新的调用方式，我们通过具体的代码理解</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">a</span>(<span class="hljs-params"></span>)</span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;哈哈哈&quot;</span>);<br>&#125;<br><span class="hljs-comment">//以前的调用</span><br><br><span class="hljs-comment">// a();</span><br>a.call();<br></code></pre></td></tr></table></figure>

<p> 在上面的代码里面，我们可以看到我们的函数通过<code>call</code>也在调用，它的调用格式如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">函数名.call(<span class="hljs-built_in">this</span>指向,...原函数参数?);<br></code></pre></td></tr></table></figure>

<p>在之前的时候，我们都说一点，普通函数在调用的时候<code>this</code>指向的是<code>window</code>这个全局对象，构造函数通过<code>new</code>调用的时候，它的<code>this</code>指向了是当前新创建对象</p>
<p><img src="https://pic.imgdb.cn/item/6125070b44eaada73907fc9e.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210824100326921"></p>
<p><strong>代码分析</strong>：</p>
<ol>
<li>在上面的代码里面，我们的<code>a()</code>是普通函数在调用，所以它的<code>this</code>指向了全局对象<code>window</code></li>
<li>我们的<code>b.call(stu1)</code>是通过<code>call</code>在调用，这样里面的<code>this</code>就指向了<code>stu1</code>这个对象</li>
</ol>
<p>通过上面的代码我们可以充分的说明一点，<code>call</code>是可以改变函数内部的<code>this</code>指向的</p>
<p>函数在通过<code>call</code>去调用的时候，其实也是可以传递参数的</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj = &#123;<br>    <span class="hljs-attr">userName</span>:<span class="hljs-string">&quot;标哥哥&quot;</span><br>&#125;;<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">abc</span>(<span class="hljs-params">x,y</span>)</span>&#123;<br>    <span class="hljs-built_in">console</span>.log(x);<br>    <span class="hljs-built_in">console</span>.log(y);<br>&#125;<br><br>abc(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>);		<span class="hljs-comment">//正常调用</span><br>abc.call(obj,<span class="hljs-number">1</span>,<span class="hljs-number">2</span>);   <span class="hljs-comment">//改变abc方法的this为 obj对象</span><br></code></pre></td></tr></table></figure>

<h4 id="通过apply来调用函数"><a href="#通过apply来调用函数" class="headerlink" title="通过apply来调用函数"></a>通过<code>apply</code>来调用函数</h4><p>函数通过<code>apply</code>调用其实与通过<code>call</code>调用作业是一样的，语法格式也非常像，如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">函数名.apply(<span class="hljs-built_in">this</span>指向,[...原函数参数]?);<br></code></pre></td></tr></table></figure>

<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj = &#123;<br>    <span class="hljs-attr">userName</span>:<span class="hljs-string">&quot;标哥&quot;</span><br>&#125;;<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">abc</span>(<span class="hljs-params"></span>)</span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好&quot;</span>);<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>);<br>&#125;<br>abc();              <span class="hljs-comment">//普通函数调用 this指向window</span><br>abc.call(obj);      <span class="hljs-comment">//call调用，this指向了obj</span><br>abc.apply(obj);     <span class="hljs-comment">//apply调用，this指向了obj</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>从上面的代码可以看到<code>call</code>与<code>apply</code>的效果是一样的，都可以改变<code>this</code>指向，它们唯一的区别应 于后面的参数</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;标哥&quot;</span><br>&#125;;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">def</span>(<span class="hljs-params">x, y</span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(x);<br>    <span class="hljs-built_in">console</span>.log(y);<br>&#125;<br>def.call(obj, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>);    <span class="hljs-comment">//call的参数是一个一个传的</span><br>def.apply(obj, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>]); <span class="hljs-comment">//apply要把传递到原函数里面的参数变成一个数组</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>通过上面的代码我们可以发现<code>call</code>在向原函数传递参数的时候是一个一个的传，而<code>apply</code>是把所有的参数变成一个数组，然后再传递过去</p>
</blockquote>
<hr>
<h2 id="3-对象在内存中的存储特点"><a href="#3-对象在内存中的存储特点" class="headerlink" title="3.对象在内存中的存储特点"></a>3.对象在内存中的存储特点</h2><h3 id="3-1对象的内存存储"><a href="#3-1对象的内存存储" class="headerlink" title="3.1对象的内存存储"></a>3.1对象的内存存储</h3><p>之前就给大家讲过，内存当中的数据结构主要有四大部分，分别是“堆，栈，链，表”。在JavaScript里面，主要用到的数据结构的存储是“堆”与“栈”这两大内存结构。<u>我们的基本数据类型是保存在内存的栈空间里面的，而我们的复杂数据类型对象是保存在我们的堆空间里面的</u></p>
<pre><code class=" mermaid">graph LR
A[上报内存]--&gt;|JS到这一步停了|B[开辟空间]--&gt;C[赋值]
D[&quot;JS是一个弱类型语言，它的空间大小由后面的值决定&quot;]
</code></pre>

<pre><code class=" mermaid">graph LR
A[上报内存]--&gt;B[开辟空间]--&gt;|强类型到这一步停下来|C[赋值]
</code></pre>

<p><img src="https://pic.imgdb.cn/item/61265d0b44eaada739d58244.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210825110748173"></p>
<p>上面的图就是基本数据类型与复杂数据类型对象的内存存储结构图，我们可以很明显的看到，基本数据类型是存放在内存的栈空间里面，而复杂数据类型是把自身的数据存放在了堆里面，而把这个堆里面的地址又存放在了栈空里面</p>
<p>复杂数据类型就通过这个栈里面的内存地址去查找堆里面的某一个内存空间（相当于栈引入了堆里面的某一个地址），所以我们也常把复杂数据类型叫<strong>引用类型</strong></p>
<ul>
<li>复杂数据类型在赋值的时候是地址赋值<code>var obj2 = obj1</code>相当于是把obj1存储在栈里面的地址赋值给了<code>obj2</code></li>
<li>基本数据类型在赋值的时候是拷贝赋值<code>var b = a;</code>就是把a在栈里面的值拷贝一份出来赋值给b</li>
</ul>
<p><strong>场景一</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">abc</span>(<span class="hljs-params">arr</span>) </span>&#123;<br>    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Array</span>.isArray(arr)) &#123;<br>        arr[<span class="hljs-number">0</span>] = <span class="hljs-string">&quot;标哥哥&quot;</span>;<br>    &#125;<br>&#125;<br><span class="hljs-keyword">var</span> stus = [<span class="hljs-string">&quot;张三&quot;</span>, <span class="hljs-string">&quot;李四&quot;</span>, <span class="hljs-string">&quot;王五&quot;</span>];      <span class="hljs-comment">//typeof stus ===&quot;object&quot;</span><br>abc(stus);<br><span class="hljs-built_in">console</span>.log(stus[<span class="hljs-number">0</span>]);           <span class="hljs-comment">//标哥哥</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>在上面的代码里面最终打印的结果是“标哥哥”，因为对象的传递的时候是“地址传递”</p>
</blockquote>
<p><strong>场景二</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">def</span>(<span class="hljs-params">a</span>) </span>&#123;<br>    a = a + <span class="hljs-number">5</span>;<br>&#125;<br><span class="hljs-keyword">var</span> x = <span class="hljs-number">10</span>;<br>def(x);<br><span class="hljs-built_in">console</span>.log(x);			<span class="hljs-comment">//10</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>上面的代码最终打印的结果就10，基本数据类型在栈里面存储，是值传递（拷贝传递）</p>
</blockquote>
<p><strong>总结点</strong>：基本数据类型在做值传递（拷贝传递）的时候是<strong>互不影响</strong>的，而复杂数据类型的对象在做传递的时候是地址传递（引用传递），它们传递的是地址，这个地址指向了同一个对象，所以它们会<strong>相互影响</strong> </p>
<hr>
<p>对象在拷贝的时候，是有两种现象的</p>
<ol>
<li>对象的浅拷贝</li>
<li>对象的深拷贝</li>
</ol>
<h3 id="3-2对象的浅拷贝"><a href="#3-2对象的浅拷贝" class="headerlink" title="3.2对象的浅拷贝"></a>3.2对象的浅拷贝</h3><p>对象的浅拷贝指提是拷贝对象在栈里面的数据</p>
<blockquote>
<p>对象的浅拷贝里面，两个对象的内存地址是相同的</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">userName</span>:<span class="hljs-string">&quot;张三&quot;</span>,<br>    <span class="hljs-attr">age</span>:<span class="hljs-number">18</span>;<br>&#125;<br><span class="hljs-keyword">var</span> obj2 = obj1;		<span class="hljs-comment">//这就是浅拷贝    这个只是拷贝了栈里面的地址，这个地址是相同的，就指向了堆里央的同一个对象</span><br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/61265e7a44eaada739da8ada.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210825141114203"></p>
<p>上图的情况，我们就叫浅拷贝，浅拷贝的过程是发生在内存的栈里面的（所有的基本数据类型都是浅拷贝）</p>
<p>如果我们要拷贝一个对象，并且拷贝出来的对象与原来的对象之间互不影响 ，我们需要使用另一种新的技术叫<strong>对象深拷贝</strong></p>
<h3 id="3-3对象的深拷贝-概念"><a href="#3-3对象的深拷贝-概念" class="headerlink" title="3.3对象的深拷贝-概念"></a>3.3对象的深拷贝-概念</h3><p>对象的深拷贝是与浅拷贝相对立的一个过程，它要深入到内存的堆里面去拷贝一份数据</p>
<blockquote>
<p>对象的深拷贝里面，拷贝出来的两个对象的内存地址是不一样的</p>
</blockquote>
<p><img src="https://pic.imgdb.cn/item/612ee1bb44eaada7390bfb34.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210825142111946"></p>
<p>通过上面的图，我们也可以看到，对象的深拷贝是到了内存的堆里面去拷贝一个相同的数据出来 </p>
<h3 id="3-4数组的深拷贝"><a href="#3-4数组的深拷贝" class="headerlink" title="3.4数组的深拷贝"></a>3.4数组的深拷贝</h3><p>数组也是一个对象，也是可以实现深拷贝的，并且之前我们已经学习过了数组的深拷贝</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr = [<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;b&quot;</span>, <span class="hljs-string">&quot;c&quot;</span>, <span class="hljs-string">&quot;d&quot;</span>, <span class="hljs-string">&quot;e&quot;</span>];<br><span class="hljs-keyword">var</span> arr1 = arr;<br>arr[<span class="hljs-number">0</span>] = <span class="hljs-string">&quot;陈子龙&quot;</span>;<br><span class="hljs-built_in">console</span>.log(arr1[<span class="hljs-number">0</span>]); <span class="hljs-comment">//陈子龙</span><br><br><span class="hljs-comment">//怎么拷贝一份数组，互不影响呢？</span><br><span class="hljs-comment">//第一种方式</span><br><span class="hljs-keyword">var</span> arr2 = arr.concat(); <span class="hljs-comment">//直接拷贝一份出来</span><br>arr2[<span class="hljs-number">0</span>] = <span class="hljs-string">&quot;标哥哥&quot;</span>;<br><br><span class="hljs-comment">//第二种方式</span><br><span class="hljs-keyword">var</span> arr3 = arr.slice();<br>arr3[<span class="hljs-number">0</span>] = <span class="hljs-string">&quot;杨佳琪&quot;</span>;<br><br><span class="hljs-comment">//第三种</span><br><span class="hljs-keyword">var</span> arr4 = arr.map(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">item, index, _arr</span>) </span>&#123;<br>    <span class="hljs-comment">// item代表的就是原数组的每一项，拿出来 ，返回到新数组里面</span><br>    <span class="hljs-keyword">return</span> item;<br>&#125;);<br></code></pre></td></tr></table></figure>

<h3 id="3-5通过Object-assign-拷贝简单对象"><a href="#3-5通过Object-assign-拷贝简单对象" class="headerlink" title="3.5通过Object.assign()拷贝简单对象"></a>3.5通过<code>Object.assign()</code>拷贝简单对象</h3><p>这个方法是JS专门提供给我们做深拷贝的方法，它的语法格式如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> 目标对象 = <span class="hljs-built_in">Object</span>.assign(目标对象,原对象);<br></code></pre></td></tr></table></figure>

<p>上面的语法格式说得很清楚，它会将源对象拷贝到目标对象里面去，然后再返回这个目标对象（返回的这个值需要就接收，不需要就不接收）</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">18</span><br>&#125;<br><span class="hljs-built_in">Object</span>.defineProperty(obj1, <span class="hljs-string">&quot;sex&quot;</span>, &#123;<br>    <span class="hljs-attr">value</span>: <span class="hljs-string">&quot;男&quot;</span>,<br>    <span class="hljs-attr">writable</span>: <span class="hljs-literal">false</span>,<br>    <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">//对象不可遍历</span><br>    <span class="hljs-attr">configurable</span>: <span class="hljs-literal">false</span><br>&#125;);<br><br><span class="hljs-comment">//先创建一个新对象，在内存的堆里面开辟了一个新空间</span><br><span class="hljs-keyword">var</span> obj2 = &#123;&#125;;<br><span class="hljs-keyword">var</span> obj3=&#123;&#125;;<br>obj3 = <span class="hljs-built_in">Object</span>.assign(obj2, obj1);      <br><span class="hljs-comment">//上面的方法是一个返回值的，需要就接收，不需要就不接收   obj3==obj2</span><br><br><span class="hljs-comment">//如果是数组操作，也是一样的</span><br><span class="hljs-keyword">var</span> arr1 = [<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;b&quot;</span>, <span class="hljs-string">&quot;c&quot;</span>, <span class="hljs-string">&quot;d&quot;</span>, <span class="hljs-string">&quot;e&quot;</span>];<br><span class="hljs-keyword">var</span> arr2 = [];<br><span class="hljs-built_in">Object</span>.assign(arr2, arr1); <br></code></pre></td></tr></table></figure>

<h3 id="3-6复杂对象的深拷贝【终极】"><a href="#3-6复杂对象的深拷贝【终极】" class="headerlink" title="3.6复杂对象的深拷贝【终极】"></a>3.6复杂对象的深拷贝【终极】</h3><p><strong>在对象里面要真正的实现复杂对象的深拷贝，只能手写方法(适用于复杂对象)</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;钟宇飞&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;男&quot;</span>,<br>    <span class="hljs-attr">telphone</span>: &#123;<br>        <span class="hljs-attr">price</span>: <span class="hljs-number">2999</span>,<br>        <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;小米手机&quot;</span>,<br>        <span class="hljs-attr">type</span>: <span class="hljs-string">&quot;国产&quot;</span><br>    &#125;<br>&#125;<br><span class="hljs-comment">//现在以上面的对象为例子，做一次深拷贝</span><br><br><span class="hljs-comment">//我给一个旧对象你，你还我一个深拷贝以后新对象</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">deepCopy</span>(<span class="hljs-params">oldObj</span>) </span>&#123;<br>    <span class="hljs-keyword">var</span> newObj = &#123;&#125;;<br>    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> oldObj != <span class="hljs-string">&quot;object&quot;</span>) &#123; <span class="hljs-comment">//说明它量一个基本数据类型，基本数据类型不用拷贝，直接给你</span><br>        <span class="hljs-keyword">return</span> oldObj;<br>    &#125;<br>    <span class="hljs-keyword">if</span> (oldObj == <span class="hljs-literal">null</span>) &#123; <span class="hljs-comment">//说明是一个null</span><br>        <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>    &#125;<br>    <span class="hljs-comment">//上面的两种情况都排除了，就说明是对象了</span><br>    <span class="hljs-comment">//第一步：获取当前对象所有的属性名</span><br>    <span class="hljs-keyword">var</span> propertyNames = <span class="hljs-built_in">Object</span>.getOwnPropertyNames(oldObj);<br>    <span class="hljs-comment">//第二步：对所有的属性名做一次遍历</span><br>    propertyNames.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">item, index, _arr</span>) </span>&#123;<br>        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> oldObj[item] == <span class="hljs-string">&quot;object&quot;</span>) &#123;<br>            <span class="hljs-comment">//说明它真的是一个对象,递归调用</span><br>            <span class="hljs-keyword">var</span> _temp = deepCopy(oldObj[item]);<br>            <span class="hljs-comment">//这个_temp就是拷贝出来的子对象</span><br>            newObj[item] = _temp;<br>        &#125; <span class="hljs-keyword">else</span> &#123;<br>            <span class="hljs-comment">//说明是基本数据类型</span><br>            newObj[item] = oldObj[item];<br>        &#125;<br>    &#125;);<br>    <span class="hljs-keyword">return</span> newObj;<br>&#125;<br><br><span class="hljs-comment">//测试</span><br><span class="hljs-keyword">var</span> a = deepCopy(<span class="hljs-number">1</span>);<br><span class="hljs-keyword">var</span> b = deepCopy(<span class="hljs-literal">null</span>);<br><span class="hljs-keyword">var</span> obj2 = deepCopy(obj1);<br></code></pre></td></tr></table></figure>

<blockquote>
<p>上面只是初级版本，我们还要改版的</p>
</blockquote>
<hr>
<h3 id="3-7对象的相等判断【重点】"><a href="#3-7对象的相等判断【重点】" class="headerlink" title="3.7对象的相等判断【重点】"></a>3.7对象的相等判断【重点】</h3><blockquote>
<p>之前我们在学习相等操作符的时候，我们学习了<code>==</code>的操作符，这个操作的操作规范我们当时是以基本数据类型为例子在做操作，现在我们学习了对象，那对象的相等判断规范是什么呢？</p>
<p><strong>规范</strong>：对象判断是否相等只有一个原则，判断他们在栈里面的地址是否相同，相同就是true，不相同就是false</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">18</span><br>&#125;<br><br><span class="hljs-keyword">var</span> obj2 = obj1;<br><br><span class="hljs-built_in">console</span>.log(obj1 == obj2);			<span class="hljs-comment">//两个对象在栈里面的地址是相同的，所以是true</span><br><br><span class="hljs-comment">//做了一次深拷贝</span><br><span class="hljs-keyword">var</span> obj3 = &#123;&#125;;<br><span class="hljs-keyword">var</span> propertyNames = <span class="hljs-built_in">Object</span>.getOwnPropertyNames(obj1);<br>propertyNames.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">item, index, _arr</span>) </span>&#123;<br>    obj3[item] = obj1[item];<br>&#125;);<br><br><span class="hljs-built_in">console</span>.log(obj1 == obj3);  <span class="hljs-comment">//false</span><br></code></pre></td></tr></table></figure>

<h3 id="3-8数组indexOf中的对象问题"><a href="#3-8数组indexOf中的对象问题" class="headerlink" title="3.8数组indexOf中的对象问题"></a>3.8数组indexOf中的对象问题</h3><p>我们之前学习数组的方法的时候，有两个方法分别是<code>indexOf</code>与<code>lastIndexOf</code>，这两个方法可以在数组当中去查找元素的索引位置 ，找到了就返回索引 ，找不到就返回-1</p>
<blockquote>
<p>这个方法在编程的底层方法里就叫“寻址”</p>
</blockquote>
<p><img src="https://pic.imgdb.cn/item/612661cc44eaada739e5990a.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210825150342011"></p>
<p>上面的截图就是我们之前在学习数组的<code>indexOf</code>方法时候的笔记，我们可以很清楚的看到里面在查找元素的时候限定了它是<code>string/number/boolean</code>三种类型，为什么呢？</p>
<p>在上面的截图里面，我们可以看到<code>indexOf</code>执行的是强判断全等<code>===</code>操作</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr = [<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-number">1</span>, <span class="hljs-literal">true</span>, <span class="hljs-string">&quot;9&quot;</span>, <span class="hljs-number">12</span>, <span class="hljs-number">33</span>, <span class="hljs-literal">false</span>, <span class="hljs-string">&quot;true&quot;</span>];<br><span class="hljs-comment">//在上面的数组里面，所有的元素都是基本数据类型，所以它们应该都是在栈里面</span><br><span class="hljs-keyword">var</span> index1 = arr.indexOf(<span class="hljs-string">&quot;9&quot;</span>);   <span class="hljs-comment">//3</span><br></code></pre></td></tr></table></figure>

<p>这个代码是没有问题的，基本数据类型是做<strong>值判断</strong>的，只要值相等就可以了，相当于<code>&quot;9&quot;===&quot;9&quot;</code>是成立的。但是对象就不一样，对象是<strong>地址判断(指向一个堆地址)</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张三&quot;</span><br>&#125;<br><span class="hljs-comment">//假设obj1的地址是0x00001,这个时候放在数组当中的对象它就是0x00001这个对象</span><br><span class="hljs-keyword">var</span> arr = [<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-number">1</span>, <span class="hljs-literal">true</span>, <span class="hljs-string">&quot;9&quot;</span>, <span class="hljs-number">12</span>, obj1, <span class="hljs-number">33</span>, <span class="hljs-literal">false</span>, <span class="hljs-string">&quot;true&quot;</span>];<br><br><span class="hljs-keyword">var</span> obj2 = obj1; <span class="hljs-comment">//浅拷贝，地址相同，相当于obj2的地址也是0x00001</span><br><br><span class="hljs-keyword">var</span> index1 = arr.indexOf(obj1); <span class="hljs-comment">//这里可以找到，返回索引5</span><br><span class="hljs-comment">//如果找对象找的是地址，0x00001在数组当中是否存在，结果肯定是存在的</span><br><span class="hljs-keyword">var</span> index2 = arr.indexOf(obj2); <span class="hljs-comment">//这里是可以找到的，返回索引5</span><br><br><span class="hljs-comment">//这里创建了一个新的对象，new Object(),在内存的堆里面开辟了新的空间，这个对象有一个新的址</span><br><span class="hljs-comment">//0x00002</span><br><span class="hljs-keyword">var</span> obj3 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;李四&quot;</span><br>&#125;;<br><span class="hljs-keyword">var</span> index3 = arr.indexOf(obj3); <span class="hljs-comment">//这里找汪不到，返回的是-1</span><br></code></pre></td></tr></table></figure>

<h2 id="4-对象番外篇"><a href="#4-对象番外篇" class="headerlink" title="4.对象番外篇"></a>4.对象番外篇</h2><h3 id="4-1对象中的this"><a href="#4-1对象中的this" class="headerlink" title="4.1对象中的this"></a>4.1对象中的this</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> name = <span class="hljs-string">&quot;标哥哥&quot;</span>;<br><span class="hljs-keyword">var</span> stu1 = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;赛罗奥特曼&quot;</span>,<br>    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;我是&quot;</span> + <span class="hljs-built_in">this</span>.name + <span class="hljs-string">&quot;,要打败我，还早两万年呢&quot;</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ol>
<li><p><strong>在全局环境下面，<code>this</code>指向全局对象<code>window</code></strong></p>
<p><img src="https://pic.imgdb.cn/item/61278f6b44eaada73921c3c4.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210826094830546"></p>
<p>直接在控制台里面打印<code>this</code>，我们可以<code>this</code>指向了<code>window</code>这一个全局对象</p>
</li>
<li><p><strong>在自定义对象的方法里面<code>this</code>指向了调用当前这一个方法的对象</strong></p>
<p><img src="https://pic.imgdb.cn/item/61278f4644eaada73921642f.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210826094948334"></p>
<p>在上面的代码当中，我们的<code>sayHello</code>这一个方法被<code>stu1</code>这一个对象在调用，所以<code>sayHello</code>这一个方法里面的<code>this</code>就指向了<code>stu1</code>，方法sayHello方法里面的<code>this.name</code>代表的就是<code>stu1.name</code> </p>
</li>
</ol>
<h3 id="4-2全局变量window-变量名"><a href="#4-2全局变量window-变量名" class="headerlink" title="4.2全局变量window.变量名"></a>4.2全局变量window.变量名</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> a=<span class="hljs-string">&quot;夹心&quot;</span>;   <span class="hljs-comment">//这其实就是全局变量</span><br><span class="hljs-built_in">console</span>.log(a);    <span class="hljs-comment">//打印夹心</span><br><span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">window</span>.a);  <span class="hljs-comment">//打印夹心</span><br><span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.a);   <span class="hljs-comment">//打印夹心   此时的this就是window</span><br></code></pre></td></tr></table></figure>

<blockquote>
<pre><code class=" mermaid">graph LR 
A[this.userName] --&gt;|this指向window| B[window.userName] 
B--&gt;|相当于| C[var userName的全局变量]
</code></pre>
</blockquote>
<blockquote>
<p>只是要注意，我一们在使用<code>window</code>调用全局的时候会把这个<code>window</code>给省略掉</p>
</blockquote>
<p><strong>案例</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> userName = <span class="hljs-string">&quot;标哥哥&quot;</span>;<br><br><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;赛罗奥特曼&quot;</span>,<br>    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.userName);<br>    &#125;<br>&#125;<br><br>obj1.sayHello(); <span class="hljs-comment">//赛罗奥特曼</span><br><br><span class="hljs-comment">//把sayHello的方法赋值给了aaa</span><br><span class="hljs-keyword">var</span> aaa = obj1.sayHello;<br><br>aaa();      <span class="hljs-comment">//标哥哥  这里是全局window调用该方法</span><br><span class="hljs-comment">//aaa()相当于window.aaa()在时候，这个时候的调用对象变成了window</span><br><span class="hljs-comment">//所以方法里面的this.userName就相当于window.userName</span><br><span class="hljs-comment">//最终打印的结果就是全局变量“标哥哥”</span><br></code></pre></td></tr></table></figure>

<h3 id="4-3构造函数中的this"><a href="#4-3构造函数中的this" class="headerlink" title="4.3构造函数中的this"></a>4.3构造函数中的this</h3><p>之前讲构造函数的时候我们就说过，构造函数在调用的时候，对象当中的<code>this</code>指向了前新创建的这个对象</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">userName,sex</span>)</span>&#123;<br>    <span class="hljs-comment">//如果这个函数是以构造函数执行的，则this就指向了这个构造函数新创建的对象</span><br>    <span class="hljs-built_in">this</span>.userName = userName;<br>    <span class="hljs-built_in">this</span>.sex = sex;<br>    <span class="hljs-built_in">this</span>.sayHello=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好，我叫&quot;</span>+<span class="hljs-built_in">this</span>.userName);<br>    &#125;<br>&#125;<br><span class="hljs-keyword">var</span> p1 = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">&quot;张三&quot;</span>,<span class="hljs-string">&quot;男&quot;</span>);<br><span class="hljs-built_in">console</span>.log(p1.sex);<br><span class="hljs-built_in">console</span>.log(p1.userName);<br>p1.sayHello();			<span class="hljs-comment">//这个方法里面的this指向了就是当前调用的对象p1</span><br></code></pre></td></tr></table></figure>

<h3 id="4-4函数不同的调用形式决定this指向"><a href="#4-4函数不同的调用形式决定this指向" class="headerlink" title="4.4函数不同的调用形式决定this指向"></a>4.4函数不同的调用形式决定this指向</h3><p>在之前我们已经讲过了函数地调用形式</p>
<blockquote>
<ol>
<li>方法名+()调用</li>
<li>var 方法名 = function(){}();函数表达式调用</li>
<li>+function(){}立即执行函数</li>
<li>new 函数名构造函数调用</li>
</ol>
</blockquote>
<p>除了上面的四种以外，我们又补充了另外的几种</p>
<h4 id="通过call来调用方法"><a href="#通过call来调用方法" class="headerlink" title="通过call来调用方法"></a>通过<code>call</code>来调用方法</h4><p>这一种情况之前已经提过了，再在再讲一次总结一下，这个call的调用主要是用于改变this的指向</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">函数名.call(<span class="hljs-built_in">this</span>指向,...原函数的参数?);<br></code></pre></td></tr></table></figure>

<p>上面就是我们之前<code>call</code>的调用方法</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> userName = <span class="hljs-string">&quot;标哥哥&quot;</span>;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sayHello</span>(<span class="hljs-params">str</span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(str);<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.userName);<br>&#125;<br><br><span class="hljs-keyword">var</span> stu1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;钟宇飞&quot;</span><br>&#125;<br><span class="hljs-keyword">var</span> stu2 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;高远航&quot;</span><br>&#125;<br><br>sayHello(<span class="hljs-string">&quot;普通调用&quot;</span>);     <span class="hljs-comment">//window.sayHello  内部的this指向window,最终打印标哥哥</span><br><br>sayHello.call(<span class="hljs-built_in">window</span>,<span class="hljs-string">&quot;通过call在调用&quot;</span>);   <span class="hljs-comment">//呼叫window来调用sayHello  打印标哥哥</span><br><br>sayHello.call(stu1,<span class="hljs-string">&quot;通过call呼叫stu1调&quot;</span>);     <span class="hljs-comment">//呼叫stu1来调用sayHello ,this指向stu1 打印钟宇飞</span><br><br>sayHello.call(stu2,<span class="hljs-string">&quot;通过call呼叫stu2调&quot;</span>);    <span class="hljs-comment">//呼叫stu2来调用sayHello,this就指向stu2,打印高远航</span><br></code></pre></td></tr></table></figure>

<p>通过<code>call</code>就可以改变原方法里面的<code>this</code>指向</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> userName = <span class="hljs-string">&quot;标哥哥&quot;</span>;<br><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;迪迦奥特曼&quot;</span>,<br>    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.userName);<br>    &#125;<br>&#125;<br><br><br>obj1.sayHello.call(<span class="hljs-built_in">window</span>);     <span class="hljs-comment">//最终打印是谁？  标哥哥</span><br><span class="hljs-comment">// obj1有一个方法sayHello，呃,我就是自己不调，我玩，我呼叫window过来调！ </span><br><span class="hljs-comment">// 所以最终this指向window,打印&quot;标哥哥&quot;</span><br></code></pre></td></tr></table></figure>

<h4 id="通过apply来调用方法"><a href="#通过apply来调用方法" class="headerlink" title="通过apply来调用方法"></a>通过<code>apply</code>来调用方法</h4><p>这个方式与上面的<code>call</code>的方式是一模一样，只是调用的参数发生了变化</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">方法名.apply(<span class="hljs-built_in">this</span>指向,[...原函数参数]?);<br></code></pre></td></tr></table></figure>

<p>上面就是apply调用的语法格式，我们现在也案例去说明</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> userName = <span class="hljs-string">&quot;标哥哥&quot;</span>;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sayHello</span>(<span class="hljs-params">str1, str2</span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(str1, str2);<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.userName);<br>&#125;<br><br><span class="hljs-keyword">var</span> stu1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;钟宇飞&quot;</span><br>&#125;<br><span class="hljs-keyword">var</span> stu2 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;高远航&quot;</span><br>&#125;<br><br>sayHello(<span class="hljs-string">&quot;第一个参数&quot;</span>, <span class="hljs-string">&quot;第二个参数&quot;</span>); <span class="hljs-comment">//this指向window,所以打印“标哥哥”</span><br><br>sayHello.apply(<span class="hljs-built_in">window</span>, [<span class="hljs-string">&quot;第一个参数&quot;</span>, <span class="hljs-string">&quot;第二个参数&quot;</span>]); <span class="hljs-comment">//this指向window,所以打印“标哥哥”</span><br><br>sayHello.apply(stu1, [<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;b&quot;</span>]);           <span class="hljs-comment">//this指向stu1,打印钟宇飞</span><br><br>sayHello.apply(stu2,[<span class="hljs-string">&quot;a&quot;</span>,<span class="hljs-string">&quot;b&quot;</span>]);             <span class="hljs-comment">//this指向stu2,打印高远航</span><br></code></pre></td></tr></table></figure>

<p><code>call</code>与<code>aplly</code>调用的原理差不多，都是呼叫谁过来调用这个方法，只是<code>apply</code>需要<strong>把原函数的参数变成一个数组</strong>，然后再传递过去</p>
<h4 id="通过bind来改变方法中的this"><a href="#通过bind来改变方法中的this" class="headerlink" title="通过bind来改变方法中的this"></a>通过<code>bind</code>来改变方法中的this</h4><p>这个调用的原理与上面的 <code>call/apply</code>非常相似，也是可以改变<code>this</code>的指向，但是有一个区别<code>bind</code>并不会立即调用这个函数，<strong>它只会返回一个新的方法</strong>，这个新的方法就是绑定了新的<code>this</code>的</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> userName = <span class="hljs-string">&quot;标哥哥&quot;</span>;<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">abc</span>(<span class="hljs-params">str</span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(str);<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.userName);<br>&#125;<br><span class="hljs-keyword">var</span> stu1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;钟宇飞&quot;</span><br>&#125;<br><br><span class="hljs-comment">//abc(&quot;普通调用&quot;);              //window.abc() this指向window 打印 标哥哥</span><br><br><span class="hljs-comment">//-----------------注意--------------------</span><br><span class="hljs-keyword">var</span> d = abc.bind(stu1, <span class="hljs-string">&quot;我是通过bind生成了新的方法&quot;</span>);<br><span class="hljs-comment">//bind只会将原方法里面的this指向stu1这个对象，并不会立即执行这个方法,并且返回一个新的方法</span><br>d();<br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/6127945244eaada7392e2337.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210826113309732"></p>
<p>在上面的代码里面还有种写法，就是在绑定<code>this</code>的时候，可以不传参，后面在调用的时候再传参也可以的</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> e = abc.bind(stu1);         <span class="hljs-comment">//这里只绑定了this,没有传递参数</span><br>e(<span class="hljs-string">&quot;我是后面传递的参数&quot;</span>);          <span class="hljs-comment">//在调用的时候去传递参数</span><br></code></pre></td></tr></table></figure>

<h3 id="4-5跨对象调用方法【重点】"><a href="#4-5跨对象调用方法【重点】" class="headerlink" title="4.5跨对象调用方法【重点】"></a>4.5跨对象调用方法【重点】</h3><p>之前我们忆经讲到了对象在调用方法的时候我们可以通过<code>call</code>与<code>apply</code>去调用，现在们就来通这一个知识点来讲讲跨对象调用方法</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> stu1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家好， 我叫&quot;</span> + <span class="hljs-built_in">this</span>.userName);<br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">var</span> stu2 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;李四&quot;</span><br>&#125;<br><span class="hljs-comment">//在上面的对象里面， 我们看到两个对象，stu1有一个属性userName及sayHello的方法</span><br><span class="hljs-comment">//而stu2只有属性userName</span><br>stu1.sayHello();        <span class="hljs-comment">//这是没有任何问题的，stu1本身就有这个sayHello的方法</span><br></code></pre></td></tr></table></figure>

<p><em>现在的问题是，我们能不能让stu2做为主体去调用stu1的sayHello方法呢？</em></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">stu2.sayHello();		<span class="hljs-comment">//这是会报错的，因为stu2没有sayHello这个方法</span><br></code></pre></td></tr></table></figure>

<p>因为<code>stu2</code>没有<code>sayHello</code>的方法，所以我们去执行上面的代码就会报错，但是我们现在有了<code>call</code>和<code>apply</code>就可以实现上面所需要的要求了</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript">stu1.sayHello.call(stu2);           <span class="hljs-comment">//把stu2叫过来去调用sayHello的方法</span><br>stu1.sayHello.apply(stu2);          <span class="hljs-comment">//这也是没有问题</span><br></code></pre></td></tr></table></figure>

<p>针对上面这种跨对象调用方法的特点，我们有什么地方可以使用到呢？</p>
<h4 id="案例一：求数组元素中的最大值"><a href="#案例一：求数组元素中的最大值" class="headerlink" title="案例一：求数组元素中的最大值"></a><strong>案例一</strong>：求数组元素中的最大值</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr = [<span class="hljs-number">1</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>];<br></code></pre></td></tr></table></figure>

<p>在以前的时候，我们如果要求上面的数组的最大值，我们就需要使用之前的<strong>比武招亲</strong>的思维，或我们的数组的<strong>归并方法</strong>去完成</p>
<p>我们可以用<code>Math.max()</code>方法得到参数中的最大值</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr = [<span class="hljs-number">1</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>];<br><span class="hljs-keyword">var</span> max = <span class="hljs-built_in">Math</span>.max(<span class="hljs-number">1</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>);   <span class="hljs-comment">//可以直接 ...arr</span><br><span class="hljs-built_in">console</span>.log(max);<br></code></pre></td></tr></table></figure>

<p>但是这么做，很麻烦，我们需要把数组中的元素一个一个的拆出来 ，然后当成参数传递到方法里面去</p>
<p>我们都知道，方法除了使用<code>方法名+()</code>调用以外，还可以使用<code>call/apply</code>的调用方式，所以上面的调用方法还可以写成如下格式</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//在原来的方法里面，max是被Math在调用，所以里面的this应该是指向Math的</span><br><span class="hljs-keyword">var</span> max = <span class="hljs-built_in">Math</span>.max.call(<span class="hljs-built_in">Math</span>, <span class="hljs-number">1</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>)<br><span class="hljs-built_in">console</span>.log(max);<br></code></pre></td></tr></table></figure>

<p>我们现在已经通过<code>call</code>在调用了，而<code>apply</code>与<code>call</code>就是在于后面的参数要变成一个<strong>数组</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//上面的方法再写成apply</span><br><span class="hljs-comment">// var max = Math.max.apply(Math,[1, 4, 6, 8, 9, 3, 2, 7]);</span><br><span class="hljs-keyword">var</span> max = <span class="hljs-built_in">Math</span>.max.apply(<span class="hljs-built_in">Math</span>, arr);   <span class="hljs-comment">//apply的参数为数组</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>虽然说是跨对象调用，但上面的max方法还是没有跨对象，调用对象都是<code>Math</code></p>
</blockquote>
<h4 id="案例二：将类数组转换成数组"><a href="#案例二：将类数组转换成数组" class="headerlink" title="案例二：将类数组转换成数组"></a><strong>案例二：将类数组转换成数组</strong></h4><blockquote>
<p>之前学习完数组以后，我们就学过了类数组</p>
<p>类数组：一个对象具备数组的特性（通过索引取值与赋值，具备length属性描述长度），但是又不具备数组的方法</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj = &#123;<br>    <span class="hljs-number">0</span>: <span class="hljs-string">&quot;a&quot;</span>,<br>    <span class="hljs-number">1</span>: <span class="hljs-string">&quot;b&quot;</span>,<br>    <span class="hljs-number">2</span>: <span class="hljs-string">&quot;c&quot;</span>,<br>    <span class="hljs-number">3</span>: <span class="hljs-string">&quot;d&quot;</span>,<br>    <span class="hljs-number">4</span>: <span class="hljs-string">&quot;e&quot;</span>,<br>    <span class="hljs-attr">length</span>: <span class="hljs-number">5</span><br>&#125;<br></code></pre></td></tr></table></figure>

<p>上面的这个对象它就是一个类数组，它具备数组的属性，但是不具备数组方法，我们希望把上面的对象（类数组）转变成一个真正的数组 <code>var arr=  [&quot;a&quot;,&quot;b,&quot;c&quot;,&quot;d&quot;,&quot;e&quot;]</code></p>
<blockquote>
<p>分析过程：首先我们先看下面的代码</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr = [<span class="hljs-string">&quot;a&quot;</span>, <span class="hljs-string">&quot;b&quot;</span>, <span class="hljs-string">&quot;c&quot;</span>, <span class="hljs-string">&quot;d&quot;</span>, <span class="hljs-string">&quot;e&quot;</span>];<br><br><span class="hljs-keyword">var</span> arr1 = arr.slice(); <span class="hljs-comment">//得到[&quot;a&quot;,&quot;b&quot;,&quot;d&quot;,&quot;d&quot;,&quot;e&quot;];</span><br><span class="hljs-comment">//arr是自身的元素，返回一个新数组，但是arr本身并没有slice方法，它使用的是原型父级的slice方法</span><br>arr.slice === arr.__proto__.slice;<br><br><span class="hljs-keyword">var</span> arr2 = arr.__proto__.slice(); <span class="hljs-comment">//出问题了</span><br><span class="hljs-comment">//上面的结果得到的是空数组</span><br><span class="hljs-comment">//原因：arr.slice()在调用的时候，slice方法的this是指向arr的，</span><br><span class="hljs-comment">//而arr.__proto__.slice()在调用的时候，slice方法是指向父级的arr.__proto__的</span><br><span class="hljs-comment">// 解决办法，让arr.__proto__.slice在调用的时候  this指向重新指回arr</span><br><br><span class="hljs-keyword">var</span> arr3 = arr.__proto__.slice.call(arr);<br></code></pre></td></tr></table></figure>

<p>经过上面的推理以后，我们发现<code>arr.slice()</code>其实就相当于<code>arr.__proto__.slice.call(arr)</code></p>
<p>在我们学习了面向对象的继承的原型以后，里面有一个句</p>
<p>一个对象的<code>__proto__</code>应该是等于它的构造函数的<code>prototype</code>的</p>
<p>arr是一个数组，它的构造函数是<code>var arr = new Array()</code>，所以它的构造函数应该是Array</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//一个对象的__proto__应该等于它的构造函数的prototype</span><br>arr.__proto__ === <span class="hljs-built_in">Array</span>.prototype; <span class="hljs-comment">//true</span><br><br>arr.__proto__.slice === <span class="hljs-built_in">Array</span>.prototype.slice;      <span class="hljs-comment">//true</span><br><br><span class="hljs-comment">//所以arr.slice ，arr.__proto__.slice，Array.prototype.slice是一个东西</span><br></code></pre></td></tr></table></figure>

<p>经过上面的推断过程以后，我们就可以得到下面的结果</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr4 = <span class="hljs-built_in">Array</span>.prototype.slice.call(arr);<br></code></pre></td></tr></table></figure>

<img src="https://pic.imgdb.cn/item/612797dc44eaada739383ed5.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210826152219354" style="zoom:50%;" />

<p><code>slice</code>方法是数组的方法，只有数组对象可以调用，它会截取自身，返回一个新数组</p>
<p>现在试想一下，<strong>如果其它对象也可以调用数组的<code>slice</code>方法</strong>，是不是也可以得到一个新数组呢</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj = &#123;<br>    <span class="hljs-number">0</span>: <span class="hljs-string">&quot;a&quot;</span>,<br>    <span class="hljs-number">1</span>: <span class="hljs-string">&quot;b&quot;</span>,<br>    <span class="hljs-number">2</span>: <span class="hljs-string">&quot;c&quot;</span>,<br>    <span class="hljs-number">3</span>: <span class="hljs-string">&quot;d&quot;</span>,<br>    <span class="hljs-number">4</span>: <span class="hljs-string">&quot;e&quot;</span>,<br>    <span class="hljs-attr">length</span>: <span class="hljs-number">5</span><br>&#125;<br><span class="hljs-comment">//我们是否可以让obj对象去调用slice方法，然后截取自身，返回一个新数组呢？【跨对象调用方法】</span><br><span class="hljs-comment">//slice本身是数组Array的方法，它会截取自身，返回一个新数组</span><br><span class="hljs-comment">//如果obj能够调用slice的方法，slice里面的this就会指向obj，也会截取自身（this）</span><br><span class="hljs-comment">// 跨对象调用方法</span><br><span class="hljs-keyword">var</span> arr = <span class="hljs-built_in">Array</span>.prototype.slice.call(obj);  <span class="hljs-comment">//[&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;, &quot;e&quot;]</span><br></code></pre></td></tr></table></figure>

<p>上面的方法是跨对象调用方法的经典案例，也是类数组转数组的经典方法</p>
<h3 id="4-6对象的运算操作"><a href="#4-6对象的运算操作" class="headerlink" title="4.6对象的运算操作"></a>4.6对象的运算操作</h3><p>在之前讲操作符的时候，我们讲过了一些最基本的操作符，如算术操作符，关系操作符等一系列运算符，在讲这些运算符的时候，我们都只是以基本数据类型为例子在讲解</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> a = <span class="hljs-number">1</span>;<br><span class="hljs-keyword">var</span> b = <span class="hljs-number">2</span>;<br><span class="hljs-keyword">var</span> c = a + b;		<span class="hljs-comment">//加法运算符</span><br><span class="hljs-keyword">var</span> d = a - b;		<span class="hljs-comment">//减法运算符</span><br></code></pre></td></tr></table></figure>

<p>之前讲算术运算符的时候，我们提到了2个重要的概念</p>
<ol>
<li>加法操作里面，字符串优先</li>
<li>减法，乘法，除法，取余操作，数字优先</li>
</ol>
<p>之前讲面向对象的时候，我们提到过一点，所有的对象最终都会继承自<code>Object</code>，所以可以理解为Object是所有对象的父级</p>
<img src="https://pic.imgdb.cn/item/612799a444eaada7393eb538.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210826161235978" style="zoom:50%;" />

<p>在<code>Object</code>对象里面，有两个特殊的方法</p>
<ol>
<li><code>toString()</code></li>
<li><code>valueOf()</code></li>
</ol>
<p>所以我们可以认为，所有的对象其实都有<code>toString()</code>及<code>valueOf()</code>的方法，那么这两个方法是用于干什么的呢？</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张三&quot;</span><br>&#125;;<br><span class="hljs-keyword">var</span> obj2 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;李四&quot;</span><br>&#125;<br>obj1.toString();            <span class="hljs-comment">//[object Object]</span><br>obj2.toString();            <span class="hljs-comment">//[object Object]</span><br></code></pre></td></tr></table></figure>

<h4 id="对象的加法运算"><a href="#对象的加法运算" class="headerlink" title="对象的加法运算"></a>对象的加法运算</h4><p>在之前讲加法操作符的时候，我们给同学样提到了，<strong>加法操作符当中实行的是字符串优先原则</strong>，所以当两个对象再进行相加的时候，其实是先调用两个对象的<code>toString()</code>方法，然后再相加</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> a = obj1 + obj2;        <span class="hljs-comment">//结果是什么？</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p><strong>代码分析</strong>：</p>
<ol>
<li>第一步：对象是不能直接相加的，在加法操作里面执行字符串优先，所以会先将对象调用toString()</li>
<li>第二步：对象调用toString()得到结果<code>[object Object]</code></li>
<li>第三步：<code>obj1 + obj2</code>的结果就可以理解为是<code>&quot;[object Object]&quot; + &quot;[object Object]&quot;</code></li>
</ol>
</blockquote>
<p>经过上面的分析以后，最终的结果一定是<code>&quot;[object Object][object Object]&quot;</code></p>
<p><em>对象在调用方法的时候，会先从自身开始查找，如果自己有就调用自己的，如果自己不存在就会到原型对象（父级）上面查找</em></p>
<p><strong>我们可以重写<code>toString</code>方法对象就会调用我们重写的方法</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>    <span class="hljs-attr">toString</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;    <br>        <span class="hljs-comment">//自已重新定义了toString</span><br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;aaa&quot;</span>;<br>    &#125;<br>&#125;;<br><span class="hljs-keyword">var</span> obj2 = &#123;<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;李四&quot;</span>,<br>    <span class="hljs-attr">toString</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-comment">//自已重新定义了toString</span><br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;bbb&quot;</span>;<br>    &#125;<br>&#125;<br>obj1.toString(); <span class="hljs-comment">//&quot;aaa&quot;        </span><br>obj2.toString(); <span class="hljs-comment">//&quot;bbb&quot;</span><br><br><span class="hljs-keyword">var</span> a = obj1 + obj2;<br><span class="hljs-built_in">console</span>.log(a);			<span class="hljs-comment">//&quot;aaabbb&quot;</span><br></code></pre></td></tr></table></figure>

<h4 id="对象的减法操作"><a href="#对象的减法操作" class="headerlink" title="对象的减法操作"></a>对象的减法操作</h4><p>在之前讲减法操作符的时候，我们都知道，减法实行的是<strong>数字优先原则</strong>，所以在对象里面，如果对象相减，则会优先调用<code>valueOf()</code>的方法，当这个方法不存在或调用失败，再调用<code>toString()</code>方法</p>
<blockquote>
<p> 你有valueOf我就调valueOf，你没有就叫<code>toString</code></p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> obj1 = &#123;<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">18</span>,<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张三&quot;</span><br>&#125;<br><span class="hljs-keyword">var</span> obj2 = &#123;<br>    <span class="hljs-attr">age</span>: <span class="hljs-number">10</span>,<br>    <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;李四&quot;</span><br>&#125;<br><br>obj1.valueOf();         <span class="hljs-comment">//得到自身    调用失败</span><br>obj2.valueOf();         <span class="hljs-comment">//得到自身	  调用失败</span><br></code></pre></td></tr></table></figure>

<p>上面的<code>obj1</code>与<code>obj2</code>同时都调用了<code>valueOf</code>得到的结果是自身</p>
<p><strong>注意</strong>：当一个对象调用<code>valueOf()</code>得到不结果，或得到的结果就是自身的时候，我们就认为它调用<code>valueOf()</code>失败了，调用失败就会退而求其次去调用<code>toString()</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs javascript"> <span class="hljs-keyword">var</span> obj1 = &#123;<br>     <span class="hljs-attr">age</span>: <span class="hljs-number">18</span>,<br>     <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>     <span class="hljs-attr">valueOf</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>         <span class="hljs-comment">//自己给自己重新定义了一个valueOf方法，不使用原型对象（父级）的方法</span><br>         <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.age;<br>     &#125;<br> &#125;<br> <span class="hljs-keyword">var</span> obj2 = &#123;<br>     <span class="hljs-attr">age</span>: <span class="hljs-number">10</span>,<br>     <span class="hljs-attr">userName</span>: <span class="hljs-string">&quot;李四&quot;</span>,<br>     <span class="hljs-attr">valueOf</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>          <span class="hljs-comment">//自己给自己重新定义了一个valueOf方法，不使用原型对象（父级）的方法</span><br>         <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.age;<br>     &#125;<br> &#125;<br><br>obj1.valueOf(); <span class="hljs-comment">//18</span><br>obj2.valueOf(); <span class="hljs-comment">//10</span><br><br><span class="hljs-keyword">var</span> a = obj1 - obj2;<br><span class="hljs-comment">//减法执行的是数字优先，所以会调用valueOf</span><br><span class="hljs-built_in">console</span>.log(a);         <span class="hljs-comment">//8</span><br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/61279ca944eaada739471b9e.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210826164157427"></p>
<blockquote>
<p>标哥说：与字符串相关的，我们就<code>toString()</code>，与数字的相关的，我们就<code>valueOf()</code></p>
</blockquote>
<p>因为乘法，除法，取余操作都是执行与减法相同的操作规则 ，所以对象的乘法，除法，以及取余操作都可以参照上面的减法来进行</p>
<h4 id="对象运算操作的练习"><a href="#对象运算操作的练习" class="headerlink" title="对象运算操作的练习"></a>对象运算操作的练习</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">console</span>.log([] + []);	<span class="hljs-comment">//&quot;&quot;	</span><br><span class="hljs-built_in">console</span>.log(&#123;&#125; + []);	<span class="hljs-comment">//[Object Object]		</span><br><span class="hljs-built_in">console</span>.log([] == ![]);	<span class="hljs-comment">//true		</span><br><br><span class="hljs-keyword">var</span> a = [<span class="hljs-number">3</span>];<br><span class="hljs-keyword">var</span> b = [<span class="hljs-number">1</span>];<br><span class="hljs-built_in">console</span>.log(a - b);  <span class="hljs-comment">//3 - 1=2        valueOf调用失败 再调用toString方法 &quot;3&quot;-&quot;1&quot;</span><br></code></pre></td></tr></table></figure>

<h2 id="5-内置对象"><a href="#5-内置对象" class="headerlink" title="5.内置对象"></a>5.内置对象</h2><h3 id="5-1Math对象"><a href="#5-1Math对象" class="headerlink" title="5.1Math对象"></a>5.1Math对象</h3><p><strong>常数</strong></p>
<p>常数就是数学或自然界里面一些固定的数，如<code>π</code>它就是一个常数</p>
<ul>
<li><code>Math.PI</code>圆周率，约等于3.14</li>
<li><code>Math.E</code>自然对数的底数，约等于2.718</li>
<li><code>Math.LN10</code>10的自然对数值，约等于2.302</li>
<li><code>Math.LN2</code>2的自然对数值，约等于0.693</li>
<li><code>Math.SQRT2</code>2的平方根，约等于1.414</li>
<li><code>Math.SQRT1_2</code>0.5的平方根，约等于0.707</li>
</ul>
<p><strong>方法</strong></p>
<ol>
<li><p>绝对值<code>Math.abs()</code>方法</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">Math</span>.abs(<span class="hljs-number">10</span>);		<span class="hljs-comment">//10</span><br><span class="hljs-built_in">Math</span>.abs(-<span class="hljs-number">5</span>);		<span class="hljs-comment">//5</span><br></code></pre></td></tr></table></figure>
</li>
<li><p>四舍五入<code>Math.round()</code>方法</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">Math</span>.round(<span class="hljs-number">3.4</span>);		<span class="hljs-comment">//保留整数四舍五入，3</span><br><span class="hljs-built_in">Math</span>.round(<span class="hljs-number">4.7</span>);		<span class="hljs-comment">//保留整数四舍五入，5</span><br></code></pre></td></tr></table></figure>

<p><strong>注意</strong>：上面的代码<code>Math.round</code>都是我们以整数为单位再进行四舍五入,如果我们想保留多位小数，怎么办呢？</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> a = <span class="hljs-number">3.1415926</span>;<br><span class="hljs-comment">//希望保留3位小数，四舍五入，怎么办呢？</span><br><span class="hljs-keyword">var</span> b = <span class="hljs-built_in">Math</span>.round(a * <span class="hljs-number">1000</span>) / <span class="hljs-number">1000</span>;<br><span class="hljs-built_in">console</span>.log(b);<br></code></pre></td></tr></table></figure>
</li>
<li><p><code>Math.floor()</code>向下取整，<strong>返回小于或等于这个数的最大整数</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">Math</span>.floor(<span class="hljs-number">99.2</span>);			<span class="hljs-comment">//99</span><br><span class="hljs-built_in">Math</span>.floor(<span class="hljs-number">15.7</span>);			<span class="hljs-comment">//15</span><br><span class="hljs-built_in">Math</span>.floor(<span class="hljs-number">11</span>);				<span class="hljs-comment">//11</span><br><span class="hljs-built_in">Math</span>.floor(-<span class="hljs-number">12.4</span>);			<span class="hljs-comment">//-13</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>Math.ceil()</code>向上取整，<strong>返回大于或等于这个数的最小整数</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">Math</span>.ceil(<span class="hljs-number">99.2</span>);			<span class="hljs-comment">//100</span><br><span class="hljs-built_in">Math</span>.ceil(<span class="hljs-number">15.7</span>);			<span class="hljs-comment">//16</span><br><span class="hljs-built_in">Math</span>.ceil(<span class="hljs-number">11</span>);				<span class="hljs-comment">//11</span><br><span class="hljs-built_in">Math</span>.ceil(-<span class="hljs-number">12.4</span>);			<span class="hljs-comment">//-12</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>到目前为止，我们处理数据就有很多种方法了，是<code>parseInt(),Math.round(),Math.floor(),Math.ceil()</code>,现在我们来将这些东西进行一些对比</p>
<p><img src="https://pic.imgdb.cn/item/612a1e1244eaada739d5991b.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210827100002848"></p>
<p>在对比上面这个操作的时候，我们发现其它的方法在操作的时候都很正常，但是<code>Math.round()</code>在执行<strong>负数的操作</strong>的时候会让很人头疼，<strong>它其实执行的是“五舍六入”的操作</strong></p>
</blockquote>
<ol>
<li><p><code>Math.pow(x,n)</code>函数，取x的n次方的结果</p>
<p>如果我们现在想取100的3次的结果 ，怎么办呢？</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">100</span>,<span class="hljs-number">3</span>);   <span class="hljs-comment">//ES6 100**3</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>Math.max()</code>方法用于求一系列数中的最大值</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">Math</span>.max(<span class="hljs-number">100</span>,<span class="hljs-number">20</span>,<span class="hljs-number">302</span>);		<span class="hljs-comment">//302</span><br></code></pre></td></tr></table></figure>

<p>之前在讲跨对象调用方法的时候，我们已经讲到过，可以通过这个方法来求出数组中的最大值</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr = [<span class="hljs-number">100</span>,<span class="hljs-number">200</span>,<span class="hljs-number">87</span>,<span class="hljs-number">54</span>,<span class="hljs-number">203</span>,<span class="hljs-number">22</span>];<br><span class="hljs-keyword">var</span> max = <span class="hljs-built_in">Math</span>.max.apply(<span class="hljs-built_in">Math</span>,arr);			<span class="hljs-comment">//203</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>Math.min()</code>求一系列数中的最小值</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">Math</span>.min(<span class="hljs-number">100</span>,<span class="hljs-number">20</span>,<span class="hljs-number">302</span>);		<span class="hljs-comment">//20</span><br><br><span class="hljs-keyword">var</span> arr = [<span class="hljs-number">100</span>,<span class="hljs-number">200</span>,<span class="hljs-number">87</span>,<span class="hljs-number">54</span>,<span class="hljs-number">203</span>,<span class="hljs-number">22</span>];<br><span class="hljs-keyword">var</span> min = <span class="hljs-built_in">Math</span>.min.apply(<span class="hljs-built_in">Math</span>,arr);			<span class="hljs-comment">//22</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>Math.sqrt(n)</code>取n的平方根</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">Math</span>.sqrt(<span class="hljs-number">9</span>);			<span class="hljs-comment">//3</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>Math.random()</code>获取0~1之间的一个随机数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">Math</span>.random();		<span class="hljs-comment">//0.4864583107356837</span><br></code></pre></td></tr></table></figure>

<p><strong>思考</strong>：如果我们想通过上面的方法获取某一个范围之内的随机数，怎么办呢？例如0~9之间随机数整怎么操作？</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> x =  <span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">10</span>);			<span class="hljs-comment">//请注意这里不包含10，产生的随机数是0~9</span><br><span class="hljs-built_in">console</span>.log(x);<br></code></pre></td></tr></table></figure>

<p><strong>小技巧</strong>：如果要产生某一个范围之内的随机数，我们可以参照下面的公式</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">Math</span>.random() * num);			<span class="hljs-comment">//num根据具体的要求来，随机数结果不包含num</span><br></code></pre></td></tr></table></figure>

<p><strong>技巧2：</strong>产生一个介于两个数之间的随机数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">Math</span>.random() * (max-min+<span class="hljs-number">1</span>)+min);			<span class="hljs-comment">//num根据具体的要求来，随机数结果不包含num</span><br><span class="hljs-comment">//20-100之间的随机数</span><br><span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">Math</span>.random() * (<span class="hljs-number">100</span>-<span class="hljs-number">20</span>+<span class="hljs-number">1</span>)+<span class="hljs-number">20</span>);	<span class="hljs-comment">//20-101之间 不包含101 取整后为100</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>Math.sin()</code>方法，求一个弧数的正弦值</p>
<blockquote>
<p>这个地方请注意，是弧度<code>rad</code>，不是角度。</p>
<p>弧度与角度有一个计算公式，不要弄混了，这个与我们这前所学习的数学里面的角度不一样</p>
<p>1°=π/180°，1rad=180°/π。</p>
</blockquote>
<table>
<thead>
<tr>
<th>度</th>
<th>0°</th>
<th>30°</th>
<th>45°</th>
<th>60°</th>
<th>90°</th>
<th>120°</th>
<th>135°</th>
<th>150°</th>
<th>180°</th>
<th>270°</th>
<th>360°</th>
</tr>
</thead>
<tbody><tr>
<td>弧度</td>
<td>0</td>
<td>π/6</td>
<td>π/4</td>
<td>π/3</td>
<td>π/2</td>
<td>2π/3</td>
<td>3π/4</td>
<td>5π/6</td>
<td>π</td>
<td>3π/2</td>
<td>2π</td>
</tr>
</tbody></table>
<p>如匀们想求出90度的弧度正弦值，应该先将90度转换成弧度</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> x = <span class="hljs-built_in">Math</span>.sin(<span class="hljs-number">90</span> * <span class="hljs-built_in">Math</span>.PI / <span class="hljs-number">180</span>);<span class="hljs-comment">//π/2		//1</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>Math.cos()</code>方法， 求一个弧度的余弦值</p>
</li>
<li><p><code>Math.tan()</code>方法，求一个弧度的正切值</p>
</li>
</ol>
<h3 id="Date对象"><a href="#Date对象" class="headerlink" title="Date对象"></a>Date对象</h3><p>在JavaScript里面用Date对象是用于表述日期的对象，它可以获取系统当前的日期与时间，也可以手动的设置日期与时间，每次通过<code>Date</code>去创建日期对象默认都是系统当前时间</p>
<p>Date它只是一个构造函数（它与我们上面的Math是不一样的，Math直接就是一个对象），我们如果需要得到日期对象，我产要通过<code>new</code>的方式来创建 </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> d = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();			<span class="hljs-comment">//得到当前的日期与时间对象</span><br><span class="hljs-comment">// Fri Aug 27 2021 10:50:42 GMT+0800 (中国标准时间)</span><br></code></pre></td></tr></table></figure>

<p>当我们在创建日期对象的时候，默认是以当前日期时间为准，如果我们需要手动的去设置一个时间，是可以向构造函数<code>Date</code>里面去传递参数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> d1 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">&quot;2021-7-3 12:00:00&quot;</span>);<br><span class="hljs-comment">//Sat Jul 03 2021 12:00:00 GMT+0800 (中国标准时间)</span><br><br><span class="hljs-keyword">var</span> d2 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2021</span>, <span class="hljs-number">7</span>, <span class="hljs-number">10</span>, <span class="hljs-number">11</span>, <span class="hljs-number">20</span>, <span class="hljs-number">40</span>);<br><span class="hljs-comment">//Tue Aug 10 2021 11:20:40 GMT+0800 (中国标准时间)</span><br></code></pre></td></tr></table></figure>

<p><strong>方法</strong></p>
<ol>
<li><p><code>Date.now()</code>方法，返回当前的时间戳。请注意，它返回的是一串数字，这个数字代表从<code>1970-1-1</code>到现在的<strong>毫秒数</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> d1 = <span class="hljs-built_in">Date</span>.now();			<span class="hljs-comment">//1630033003696</span><br></code></pre></td></tr></table></figure>

<p>这一串数字代表的就是当前的时间，所以后期学到数据库去的时候，我存入在数据库中的时间都是以这个数值在存储</p>
<p>通过这个时间戳，我们就可以知道它的具体时间</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> currentDate = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">1630033003696</span>);<br><span class="hljs-comment">//这样就得到了这个时间戳的具体时间</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>getFullYear()</code>获取年份方法</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> d = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();<br>d.getFullYear();			<span class="hljs-comment">//2021</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>getMonth()</code>获取月份的方法</p>
<blockquote>
<p>一年有12个月，但是月份是从0开始的</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">d.getMonth();		<span class="hljs-comment">//现在是8月，得到的结果应该是7</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>getDate()</code>获取当前的天数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">d.getDate();		<span class="hljs-comment">//今天是8月27，所以结果是27</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>getDay()</code>获取星期几</p>
<blockquote>
<p>星期是从0开始的，但是一个星期的第一天是星期天</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">d.getDay();		<span class="hljs-comment">//今天星期五		得到结果5</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>getHours()</code>获取小时数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">d.getHours();			<span class="hljs-comment">//获取小时数 11</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>getMinutes()</code>获取分钟</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">d.getMinutes();		    <span class="hljs-comment">//获取分钟数 16</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>getSeconds()</code>获取秒钟</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">d.getSeconds();			<span class="hljs-comment">//获取秒钟数 </span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>getMilliseconds()</code>获取毫秒数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">d.getMillseconds();		<span class="hljs-comment">//获取毫秒</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>上面的几个方法我们是可以通过<code>get</code>来获取到日期与时间的相关信息，与之相对应的我们还有<code>set</code>相关的赋值方法</p>
<p>如果我们想某一个日期对象进行赋值，则可以按下面的方式进行操作</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> d = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();			<span class="hljs-comment">//当前时间2021-8-27</span><br><span class="hljs-comment">//我现在希望改变它的年份</span><br>d.setFullYear(<span class="hljs-number">1999</span>);<br><span class="hljs-comment">//改变月份,我现在希望设置10月</span><br>d.setMonth(<span class="hljs-number">9</span>);				<span class="hljs-comment">//注意月份是从0开始的,它没有上限，如果大于11，则会向年份上面进位</span><br><span class="hljs-comment">//同样的天数也是一样的，天数大于30，或31，就会向月份上面进位</span><br></code></pre></td></tr></table></figure>
</blockquote>
</li>
<li><p><code>toString()</code>方法</p>
<p>日期对象可以调用这个方法将日期转换成字符串，但是在转换的过程当中，我们要注意一些事项</p>
<ul>
<li><code>toString()</code></li>
<li><code>toDateString()</code></li>
<li><code>toTimeString()</code></li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript">d.toString();<br><span class="hljs-comment">//Fri Aug 27 2021 11:24:30 GMT+0800 (中国标准时间);</span><br><br>d.toDateString();			<span class="hljs-comment">//Fri Aug 27 2021</span><br><br>d.toTimeString();			<span class="hljs-comment">//11:25:19 GMT+0800 (中国标准时间)</span><br></code></pre></td></tr></table></figure>

<p>我们一般情况下，会很少使用这一个<code>toString()</code>的方法</p>
</li>
<li><p><code>toLocaleString()</code>转换成本地时间，也就是你电脑右下角格式的时间</p>
<ul>
<li><code>toLocaleString()</code></li>
<li><code>toLocaleDateString()</code></li>
<li><code>toLocaleTimeString()</code></li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript">d.toLocaleString();				<span class="hljs-comment">//2021/8/27 上午11:27:49</span><br>d.toLocaleDateString();			<span class="hljs-comment">//2021/8/27</span><br>d.toLocaleTimeString();			<span class="hljs-comment">//上午11:28:42</span><br></code></pre></td></tr></table></figure>

<p>所以我们一般将时间对象转换成字符串的时候，我们都是使用这一个方法再进行（或单独编写一个方法）</p>
</li>
<li><p><code>toGMTString()</code>将当前时间以GMT格式去显示为字符串</p>
<p>GMT时间就是0时区的时间</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> d = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();		<span class="hljs-comment">//Fri Aug 27 2021 11:30:29 GMT+0800 (中国标准时间)</span><br><span class="hljs-comment">//这个时候得到时间是一个东8区  GMT+8 的这个时间， 我们要转换成0时间的标准时间</span><br>d.toGMTString();		<span class="hljs-comment">//Fri, 27 Aug 2021 03:31:14 GMT</span><br></code></pre></td></tr></table></figure>

</li>
</ol>
<p><strong>扩展</strong>：如果现在有2个时间，我们需要将这2个时间进行比较，或相减，针对这一种业务逻辑场景，我们怎么处理呢？</p>
<ul>
<li>第一种场景 ：我想看两个时间相隔多久</li>
<li>第二种场景：我想看哪一个时间在前面，哪一个时间在后面（比较大小）</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> d1 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">&quot;2021-12-31&quot;</span>);<br><span class="hljs-keyword">var</span> d2 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">&quot;2021-8-27&quot;</span>);<br></code></pre></td></tr></table></figure>

<ul>
<li><p><input checked="" disabled="" type="checkbox">  现在我如果想看两个时间谁在前面，谁在后面怎么办呢？</p>
</li>
<li><p><input checked="" disabled="" type="checkbox">  如果我想看一下两个时间相隔多少天，怎么办呢？</p>
</li>
</ul>
<p>如果在日期对象上面要做业务逻辑操作的时候，一定不能直接操作，要将时间转换成时间戳以后再操作。</p>
<p>一个日期对象如果想获取时间戳，可以调用<code>getTime()</code>这个方法</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> d1Time = d1.getTime();			<span class="hljs-comment">//1640908800000</span><br><span class="hljs-keyword">var</span> d2Time = d2.getTime();			<span class="hljs-comment">//1629993600000</span><br></code></pre></td></tr></table></figure>

<p>现有有了这个具体的数值以后，我们就可以进行判断与操作了</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">if</span>(d1Time &gt; d2Time)&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;第1个时间在第2个时间后面&quot;</span>);<br>&#125;<br><span class="hljs-keyword">else</span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;第2个时间在第1个时间的后面&quot;</span>);<br>&#125;<br></code></pre></td></tr></table></figure>

<p>同样的通过上面的时间戳，我们也可以计算出两个数的时间天数间隔</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//两个时间相隔多少天</span><br><span class="hljs-keyword">var</span> totalDay = <span class="hljs-built_in">parseInt</span>((d1Time - d2Time) / <span class="hljs-number">1000</span> / <span class="hljs-number">60</span> / <span class="hljs-number">60</span> / <span class="hljs-number">24</span>);<br><span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;距离2022年元旦还有&quot;</span> + totalDay + <span class="hljs-string">&quot;天&quot;</span>);<br></code></pre></td></tr></table></figure>

<blockquote>
<p>在这里我要跟同学们说一点，两个时间对象如果直接相减，<em>我们之前在讲对象的的运算符的时候，我们说过，<strong>减法是数字优先，它会调用<code>valueOf</code>的方法</strong></em></p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript">d1.valueOf();		<span class="hljs-comment">//1640908800000</span><br>d2.valueOf();		<span class="hljs-comment">//1629993600000</span><br></code></pre></td></tr></table></figure>

<p>我们发现Date对象在**<code>valueOf</code>方法其实就是<code>getTime()</code>**的方法，所以我们可以直接将两个对象相减，或判断大小</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> d1 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">&quot;2021-12-31&quot;</span>);<br><span class="hljs-keyword">var</span> d2 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">&quot;2021-8-27&quot;</span>);<br><span class="hljs-keyword">if</span>(d1&lt;d2)&#123;<br>    <span class="hljs-comment">//这么判断也是可以的，因为内部的valueOf方法与getTime方法一样，都返回时间戳</span><br>&#125;<br><span class="hljs-keyword">var</span> times = d1 - d2;<br></code></pre></td></tr></table></figure>

<hr>
<h3 id="延时调用与循环调用"><a href="#延时调用与循环调用" class="headerlink" title="延时调用与循环调用"></a>延时调用与循环调用</h3><p>延时调用也叫一次性定时器，循环调用也叫循环定时器。定时器可以反它理解为一个闹钟</p>
<h4 id="延时调用"><a href="#延时调用" class="headerlink" title="延时调用"></a>延时调用</h4><p>延时调用相当于一次性的一个闹钟，这个闹钟在间隔多长时间以后就会去响</p>
<p>这一点概念我们可以把它引入我们的编程当。在编写程序的时候，我们如果有一些代码不需要立刻时间，要等一段时间以后去执行，我们就可以使用延时调用</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">abc</span>(<span class="hljs-params"></span>)</span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;我要说标哥哥非常帅&quot;</span>);<br>&#125;<br>abc();			<span class="hljs-comment">//这个方法会立即执行</span><br></code></pre></td></tr></table></figure>

<p><strong>延时调用</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//超时调用，延时调用</span><br><span class="hljs-keyword">var</span> timeId = <span class="hljs-built_in">setTimeout</span>(abc, <span class="hljs-number">5000</span>);<br><span class="hljs-comment">//第一个参数：代表时间到了以后要做事件，它接收一个回调函数（方法名）</span><br><span class="hljs-comment">//第二个参数：以毫秒为单位，设置延时的时间</span><br><span class="hljs-comment">//这个方法会返回一个定时器的编写，我们可以通过这个定时器的编写，来取消这个定时器</span><br></code></pre></td></tr></table></figure>

<p>通过上面的代码，我们已经掌握了延时调用的基本使用了，现在我们继续</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">abc</span>(<span class="hljs-params">userName</span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家都说&quot;</span> + userName + <span class="hljs-string">&quot;很帅&quot;</span>);<br>&#125;<br><br><span class="hljs-comment">//abc的方法里面接收一个参数userName</span><br><span class="hljs-comment">//现在如果希望在5秒钟以后调用abc,并向方法里面传递参数“标哥哥”，怎么办呢</span><br><span class="hljs-keyword">var</span> timeId = <span class="hljs-built_in">setTimeout</span>(abc, <span class="hljs-number">5000</span>, <span class="hljs-string">&quot;标哥哥&quot;</span>, <span class="hljs-number">18</span>);<br><span class="hljs-comment">//从第三个参数，它就是向回调函数里面传递参数了</span><br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/612a1f0044eaada739d70a05.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210827144027637"></p>
<p><strong>用匿名函数代替上面的写法</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> timeId = <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">userName, age</span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;大家都说&quot;</span> + userName + <span class="hljs-string">&quot;很帅&quot;</span>);<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;他只有&quot;</span> + age + <span class="hljs-string">&quot;岁&quot;</span>);<br>&#125;, <span class="hljs-number">5000</span>, <span class="hljs-string">&quot;徐文铭&quot;</span>,<span class="hljs-number">20</span>);<br></code></pre></td></tr></table></figure>

<h4 id="循环调用"><a href="#循环调用" class="headerlink" title="循环调用"></a>循环调用</h4><p>循环调用也叫循环定时器，它就相当于这个闹钟每隔一个固定时间就去执行一次，它不是一次性的（可以理解为同学样手机上面的起床闹钟，每隔24个小时就会响一次，提醒同学们早上要起床了）</p>
<p>循环调用的语法格式与上面的延时调用的语法格式是保持一致的，它使用<code>setInterval()</code>这个函数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">abc</span>(<span class="hljs-params"></span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;他们都说标哥很帅!&quot;</span> + <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toLocaleString());<br>&#125;<br><span class="hljs-comment">//我现在希望上面的代码每隔5秒钟说就说一次，怎么办呢</span><br><br><span class="hljs-keyword">var</span> timeId = <span class="hljs-built_in">setInterval</span>(abc, <span class="hljs-number">5000</span>);<br></code></pre></td></tr></table></figure>

<p>同理，它也可以给参数，也可以设置回调函数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> timeId = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">userName, age</span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(userName + <span class="hljs-string">&quot;真帅&quot;</span>);<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;他只有&quot;</span> + age + <span class="hljs-string">&quot;岁&quot;</span>);<br>&#125;, <span class="hljs-number">5000</span>,<span class="hljs-string">&quot;方华升&quot;</span>,<span class="hljs-number">20</span>);<br></code></pre></td></tr></table></figure>

<h4 id="定时器的取消"><a href="#定时器的取消" class="headerlink" title="定时器的取消"></a>定时器的取消</h4><ol>
<li><p>延时调用取消</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">clearTimeout</span>(定时器编写);<br><span class="hljs-comment">//如定时器编写为1</span><br><span class="hljs-built_in">clearTimeout</span>(<span class="hljs-number">1</span>);<br></code></pre></td></tr></table></figure>
</li>
<li><p>循环调用的取消</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">clearInterval</span>(定时器编号);<br><span class="hljs-comment">//如定时器编号为1</span><br><span class="hljs-built_in">clearInterval</span>(<span class="hljs-number">1</span>);<br></code></pre></td></tr></table></figure>

</li>
</ol>
<h2 id="包装对象"><a href="#包装对象" class="headerlink" title="包装对象"></a>包装对象</h2><blockquote>
<p>包装对象其实也是我们的内置对象</p>
</blockquote>
<p>我们在之前讲数据类型的时候，提到了5种基本数据类型</p>
<ul>
<li><code>string</code>字符串类型</li>
<li><code>number</code>数字类型</li>
<li><code>boolean</code>布尔类型</li>
<li><code>undefined</code>未定义类型</li>
<li><code>null</code>空类型</li>
</ul>
<p>以后面后学到的对象</p>
<p>所谓的包装对象其实是为了基本数据类型的<code>string/number/boolean</code>来服务的</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;hello&quot;</span>;<br>str.length;                 <span class="hljs-comment">//像对象一样调用属性</span><br>str.toUpperCase();          <span class="hljs-comment">//像对象一样调用方法</span><br><br><br><span class="hljs-keyword">var</span> flag = <span class="hljs-literal">true</span>;<br>flag.toString();            <span class="hljs-comment">//像对象一样调用方法</span><br><br><span class="hljs-keyword">var</span> a = <span class="hljs-number">123</span>;<br>a.toFixed(<span class="hljs-number">2</span>);               <span class="hljs-comment">//像对象一样调用方法</span><br></code></pre></td></tr></table></figure>

<p>上面的三个变量明明都是基本数据类型，为什么会有方法与属性可以调用？方法与属性是对象才有的特点吗，基本数据类型怎么会有呢？</p>
<p><img src="https://pic.imgdb.cn/item/612a200b44eaada739da7d46.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210827154311531"></p>
<p><img src="https://pic.imgdb.cn/item/612a201944eaada739dab010.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210827154604934"></p>
<p>包装对象有一个像这样的一个点</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript">str.__proto__ === <span class="hljs-built_in">String</span>.prototype;<br>flag.__proto__ === <span class="hljs-built_in">Boolean</span>.prototype;<br>a.__proto__ === <span class="hljs-built_in">Number</span>.prototype;<br></code></pre></td></tr></table></figure>

<p>所以根据上面的特点，我们可以理解为下面的代码【标哥的理解方式】</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;hello&quot;</span>;<br><span class="hljs-comment">//相当于</span><br><span class="hljs-keyword">var</span> str = <span class="hljs-keyword">new</span> <span class="hljs-built_in">String</span>(<span class="hljs-string">&quot;hello&quot;</span>);<br><br><span class="hljs-keyword">var</span> flag = <span class="hljs-literal">true</span>;<br><span class="hljs-comment">//相当于</span><br><span class="hljs-keyword">var</span> flag = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Boolean</span>(<span class="hljs-literal">true</span>);<br><br><span class="hljs-keyword">var</span> a = <span class="hljs-number">123</span>;<br><span class="hljs-comment">//相当于</span><br><span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Number</span>(<span class="hljs-number">123</span>);<br></code></pre></td></tr></table></figure>

<p>通过上面的分析，我们就发现基本数据类型<code>string/number/boolean</code>是可以像对象一样操作，是因为它们本身是基本数据类型，但是系统会同步的创建一个对象</p>
<h3 id="String对象"><a href="#String对象" class="headerlink" title="String对象"></a>String对象</h3><p>String字符串对象是我们JavaScript当中最常见的一种包装对象，它个包装对象对象的就是基本数据类型当中的<code>string</code>类型</p>
<blockquote>
<p>字符串其实是可以把它理解为一个字符数组，它具备数组里面的大部分方法与属性</p>
</blockquote>
<p>现在我们以下面的字符串为例子，来学习</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;hello-world&quot;</span>;<br></code></pre></td></tr></table></figure>

<ol>
<li><p><code>length</code>属性</p>
<p>返回当前字符串的字符个数，也就是字符串的长度</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">str.length;		<span class="hljs-comment">//11</span><br></code></pre></td></tr></table></figure>
</li>
<li><p>索引取值</p>
<p>之前讲数组的时候说过数组的元素是通过索引取值的，字符串是一个特殊的字符数组，所以也可能通过索引取值</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript">str[<span class="hljs-number">0</span>];		<span class="hljs-comment">//h</span><br>str[<span class="hljs-number">4</span>];		<span class="hljs-comment">//o</span><br></code></pre></td></tr></table></figure>

<p><strong>注意</strong>：字符串只能通过索引取值 ，不能通过索引赋值</p>
</li>
<li><p><code>concat()</code>拼接字符串</p>
<p>这个方法在数组里面也是拼接的意思，在字符串里面，它会拼接一个字符串，返回新字符串，原字符串不变</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;hello&quot;</span>;<br><span class="hljs-keyword">var</span> userName = <span class="hljs-string">&quot;标哥哥&quot;</span>;<br><span class="hljs-keyword">var</span> result = str.concat(userName);		<span class="hljs-comment">//hello标哥哥</span><br><br><span class="hljs-comment">//其实这个方法基本上不会用，因为我们可以直接使用加法操作符</span><br><span class="hljs-keyword">var</span> result2 = str + userName;<br></code></pre></td></tr></table></figure>
</li>
<li><p><code>slice(start?,end?)</code>方法</p>
<p>这个方法在数组里面也是存在的，它是用于截取数组的元素。在字符串里面的用法也是一样的，它会从起始位置开始，截到end的位置 ，但不包含end，原字符串不变</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript">str.slice(<span class="hljs-number">0</span>,<span class="hljs-number">4</span>);			<span class="hljs-comment">//&quot;hell&quot;</span><br>str.slice(<span class="hljs-number">3</span>,-<span class="hljs-number">1</span>);		<span class="hljs-comment">//&quot;lo-worl&quot;</span><br>str.slice(-<span class="hljs-number">4</span>,-<span class="hljs-number">1</span>);		<span class="hljs-comment">//&quot;orl&quot;</span><br>str.slice(<span class="hljs-number">1</span>);			<span class="hljs-comment">//&quot;ello-world&quot;</span><br>str.slice();			<span class="hljs-comment">//&quot;hello-world&quot;</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>substring(start,end?)</code>截取字符串，返回新字符串，原字符串不变</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript">str.substring(<span class="hljs-number">0</span>,<span class="hljs-number">4</span>);		<span class="hljs-comment">//&quot;hell&quot;</span><br>str.substring(<span class="hljs-number">1</span>);		<span class="hljs-comment">//&quot;ello-world&quot;</span><br></code></pre></td></tr></table></figure>

<p><strong>注意</strong>：</p>
<ul>
<li><code>substring()</code>开始位置不能省略**(标准，虽然省略也可以使用)**，结果位置可以省略，<code>slice()</code>开始与结束都可以省略。</li>
<li><code>substring()</code>不建议使用负数做为参数，<code>slice</code>可以使用负数做为参数</li>
<li><code>substring</code>与<code>slice</code>有个共同点，在截取的时候，都不包含<code>end</code></li>
</ul>
</li>
<li><p><code>substr(start,length?)</code>截取字符串，从start位置开始，截取length长度，原字符串不变</p>
<blockquote>
<p>这点与上面的两个方法都不一样，这个方法的第2个参数是截取的长度</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript">str.substr(<span class="hljs-number">1</span>,<span class="hljs-number">4</span>);			<span class="hljs-comment">//&quot;ello&quot;</span><br>str.substr(<span class="hljs-number">3</span>);				<span class="hljs-comment">//&quot;lo-world&quot;,从索引为3的位置开始，一直截取到最后</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>indexOf/lastIndexOf</code>查找匹配的字符串，与数组里面的方法保持一致，找到以后返回索引 ，找不到返回-1</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str1 = <span class="hljs-string">&quot;我爱北京天安门，天安门上太阳升&quot;</span>;<br>str1.indexOf(<span class="hljs-string">&quot;北&quot;</span>);			<span class="hljs-comment">//2</span><br>str1.indexOf(<span class="hljs-string">&quot;天&quot;</span>);			<span class="hljs-comment">//4</span><br>str1.indexOf(<span class="hljs-string">&quot;哈&quot;</span>);			<span class="hljs-comment">//-1</span><br>str1.indexOf(<span class="hljs-string">&quot;天&quot;</span>,<span class="hljs-number">5</span>);		<span class="hljs-comment">//8</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>split()</code>方法，将字符串以指定的字符隔开，变成数组</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;hello-world&quot;</span>;<br>str.split(<span class="hljs-string">&quot;-&quot;</span>);			<span class="hljs-comment">//[&quot;hello&quot;, &quot;world&quot;]</span><br><span class="hljs-comment">//如果我们以一个空字符串去隔开，结果如下</span><br>str.split(<span class="hljs-string">&quot;&quot;</span>);			<span class="hljs-comment">//[&quot;h&quot;, &quot;e&quot;, &quot;l&quot;, &quot;l&quot;, &quot;o&quot;, &quot;-&quot;, &quot;w&quot;, &quot;o&quot;, &quot;r&quot;, &quot;l&quot;, &quot;d&quot;]</span><br></code></pre></td></tr></table></figure>

<p>这一个方法其实就是数组<code>join()</code>方法的反向操作</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> arr1 = [<span class="hljs-string">&quot;hello&quot;</span>,<span class="hljs-string">&quot;world&quot;</span>];<br>arr1.join(<span class="hljs-string">&quot;-&quot;</span>);			<span class="hljs-comment">//&quot;hello-world&quot;;</span><br><span class="hljs-keyword">var</span> arr2 = [<span class="hljs-string">&quot;h&quot;</span>, <span class="hljs-string">&quot;e&quot;</span>, <span class="hljs-string">&quot;l&quot;</span>, <span class="hljs-string">&quot;l&quot;</span>, <span class="hljs-string">&quot;o&quot;</span>, <span class="hljs-string">&quot;-&quot;</span>, <span class="hljs-string">&quot;w&quot;</span>, <span class="hljs-string">&quot;o&quot;</span>, <span class="hljs-string">&quot;r&quot;</span>, <span class="hljs-string">&quot;l&quot;</span>, <span class="hljs-string">&quot;d&quot;</span>];<br>arr2.join(<span class="hljs-string">&quot;&quot;</span>);			<span class="hljs-comment">//&quot;hello-world&quot;</span><br></code></pre></td></tr></table></figure>

<p>后期我们在工作过程当中经常会将这2个方法联合起来一起使用</p>
</li>
<li><p><code>charAt(index)</code>通过索引来获取字符串里面的某个字符</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript">str.charAt(<span class="hljs-number">0</span>);<br><span class="hljs-comment">//相当于</span><br>str[<span class="hljs-number">0</span>];<br></code></pre></td></tr></table></figure>
</li>
<li><p><code>charCodeAt(index)</code>通过索引来获取字符串里面某一个字符串<code>unicode</code>编码，如果是英文就会返回<code>ascii</code>码</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;我爱你&quot;</span>;<br>str.charCodeAt(<span class="hljs-number">0</span>);			<span class="hljs-comment">//字符“我”的unicode编码 		25105</span><br>str.charCodeAt(<span class="hljs-number">2</span>);			<span class="hljs-comment">//字符“你”的unicode编码 		20320</span><br><span class="hljs-string">&quot;我&quot;</span> &gt; <span class="hljs-string">&quot;你&quot;</span>;				   <span class="hljs-comment">//true  中文字符串在比较的的时候，得到的unicode编码 </span><br><br><span class="hljs-keyword">var</span> str2 = <span class="hljs-string">&quot;abc&quot;</span>;<br>str2.charCodeAt(<span class="hljs-number">0</span>);			<span class="hljs-comment">//&quot;97&quot;  得到ascii码</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>String.fromCharCode()</code>通过某珍上编码反向的得到字符串</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str1 = <span class="hljs-built_in">String</span>.fromCharCode(<span class="hljs-number">97</span>);			<span class="hljs-comment">//得到结果&quot;a&quot;;</span><br><span class="hljs-keyword">var</span> str2 = <span class="hljs-built_in">String</span>.fromCharCode(<span class="hljs-number">65</span>);			<span class="hljs-comment">//得到结果&quot;A&quot;;</span><br><span class="hljs-keyword">var</span> str3 = <span class="hljs-built_in">String</span>.fromCharCode(<span class="hljs-number">25015</span>);		<span class="hljs-comment">//得到结果&quot;我&quot;</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>startsWith()</code>判断某个字符串是以什么开始的</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;我爱北京天安门&quot;</span>;<br>str.startsWith(<span class="hljs-string">&quot;我&quot;</span>);				<span class="hljs-comment">//true</span><br>str.startsWith(<span class="hljs-string">&quot;我爱&quot;</span>);				<span class="hljs-comment">//true</span><br>str.startsWith(<span class="hljs-string">&quot;你&quot;</span>);				<span class="hljs-comment">//false</span><br><br><span class="hljs-keyword">var</span> url1 = <span class="hljs-string">&quot;http://www.softeem.xin&quot;</span>;<br>url.startsWith(<span class="hljs-string">&quot;http&quot;</span>);				<span class="hljs-comment">//true</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>endsWith()</code>判断某个字符串是以什么结束</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;我爱北京天安门&quot;</span>;<br>str.endsWith(<span class="hljs-string">&quot;天安门&quot;</span>);					<span class="hljs-comment">//true</span><br><br><span class="hljs-keyword">var</span> url1 = <span class="hljs-string">&quot;http://www.softeem.xin&quot;</span>;<br>url1.endsWith(<span class="hljs-string">&quot;com&quot;</span>);					  <span class="hljs-comment">//false</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>includes()</code>判断某个字符串是否包含</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;我爱北京天安门&quot;</span>;<br>str.includes(<span class="hljs-string">&quot;北京&quot;</span>);				<span class="hljs-comment">//true</span><br></code></pre></td></tr></table></figure>

<p>这个功能点的实现其实通过<code>indexOf/lastIndexOf</code>也是可以的</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript">str.indexOf(<span class="hljs-string">&quot;北京&quot;</span>);				<span class="hljs-comment">//2   </span><br></code></pre></td></tr></table></figure>

<p>只要结果不是-1就包含</p>
</li>
<li><p><code>trim()/trimLeft()/trimRight()</code>去除字符串左边、右边或左右两边的空格</p>
<ul>
<li><code>trim()</code>去除两边的空格</li>
<li><code>trimLeft()</code>只去除左边的空格</li>
<li><code>trimRight()</code>只去除右边的空格</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;   我爱北京天安门   &quot;</span>;<br>str.trim();						<span class="hljs-comment">//&quot;我爱北京天安门&quot;</span><br>str.trimLeft();					<span class="hljs-comment">//&quot;我爱北京天安门   &quot;</span><br>str.trimRight();				<span class="hljs-comment">//&quot;   我爱北京天安门&quot;</span><br></code></pre></td></tr></table></figure>

<p>现在如果是有下面的字符串需要去掉空格呢</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot; 我 爱 北 京 天 安 门 &quot;</span>;<br></code></pre></td></tr></table></figure>

<p>如果这个空格在中间，怎么办呢？后面要用到正则表达式+替换去完成</p>
</li>
<li><p><code>replace()</code>方法，将字符串中间字符替换成指定的字符</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;我爱你&quot;</span>;<br><span class="hljs-comment">//我要把“爱”替换成“恨”</span><br><span class="hljs-keyword">var</span> str1 = str.replace(<span class="hljs-string">&quot;爱&quot;</span>,<span class="hljs-string">&quot;恨&quot;</span>);			<span class="hljs-comment">//“我恨你”</span><br><br><span class="hljs-keyword">var</span> str2 = <span class="hljs-string">&quot;我爱你，你爱我吗&quot;</span>;<br><span class="hljs-comment">//将上面字符串当中的“爱”换成“恨”</span><br><span class="hljs-keyword">var</span> str3 = str2.replace(<span class="hljs-string">&quot;爱&quot;</span>,<span class="hljs-string">&quot;恨&quot;</span>);			<span class="hljs-comment">//&quot;我恨你，你爱我吗&quot;</span><br></code></pre></td></tr></table></figure>

<p>这个时候我们就发现一个问题，<code>replace</code>只替换了第一次找到的值，后面没有替换，如果希望全局替换，则要结合<strong>正则表达式使用</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str4 = str2.replace(<span class="hljs-regexp">/爱/g</span>,<span class="hljs-string">&quot;恨&quot;</span>);<br></code></pre></td></tr></table></figure>
</li>
<li><p><code>toUpperCase()/toLowerCase()</code>。这两个方法可以将字符串转换成大写或小写，原字符串不变，会得到一个新的字符串</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript">str.toUpperCase();			<span class="hljs-comment">//&quot;HELLO-WORLD&quot;				转换为大写字母</span><br><span class="hljs-keyword">var</span> str1 = <span class="hljs-string">&quot;My name is BiaoGege&quot;</span>;<br>str.tolLowerCase();			<span class="hljs-comment">//&quot;my name is biaogege&quot;		转换为小写字母</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>anchor</code>锚方法</p>
<p>该方法会将字符串生成一个指定的a标签的HTML代码</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;http://www.softeem.xin&quot;</span>;<br>str.anchor();<br><span class="hljs-comment">// &lt;a name=&quot;bbb&quot;&gt;http://www.softeem.xin&lt;/a&gt;</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>big()</code>与<code>small()</code>的方法</p>
<p>这两个方法也会将字符串生成指定的HTML标签代码</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str = <span class="hljs-string">&quot;hello-world&quot;</span>;<br>str.big();		<span class="hljs-comment">//&quot;&lt;big&gt;hello-world&lt;/big&gt;&quot;</span><br>str.small();	<span class="hljs-comment">//&quot;&lt;small&gt;hello-world&lt;/small&gt;&quot;</span><br></code></pre></td></tr></table></figure>

<p>这里说一点，第18个方法与第19个方法基本上是用不到的，我们也很少使用</p>
</li>
<li><p><code>padStart(maxLength,fillString)</code>方法，这个方法是将字符串以指定的长度补齐在左边</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str1 = <span class="hljs-string">&quot;1&quot;</span>;<br><span class="hljs-keyword">var</span> str2 = <span class="hljs-string">&quot;56&quot;</span>;<br><span class="hljs-keyword">var</span> str3 = <span class="hljs-string">&quot;463&quot;</span>;<br><br>str1.padStart(<span class="hljs-number">3</span>,<span class="hljs-number">0</span>);		<span class="hljs-comment">//&quot;001&quot;			总长度为3，剩下不够的在左边补0</span><br>str2.padStart(<span class="hljs-number">6</span>,<span class="hljs-number">0</span>);		<span class="hljs-comment">//&quot;000056&quot;		总长度为6，剩下不够的在左边补0</span><br>str3.padStart(<span class="hljs-number">3</span>,<span class="hljs-number">0</span>);		<span class="hljs-comment">//&quot;463&quot;			总长度为3，原来的长度是够的，所以不用补0</span><br>str3.padStart(<span class="hljs-number">2</span>,<span class="hljs-number">0</span>);		<span class="hljs-comment">//&quot;463&quot;			总长度为2，原长度超过，不用补</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>padEnd(maxLength,fillString)</code>方法，这个方法与上面的方法刚好相反，在结束的位置填充</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> str1 = <span class="hljs-string">&quot;1&quot;</span>;<br><span class="hljs-keyword">var</span> str2 = <span class="hljs-string">&quot;56&quot;</span>;<br><span class="hljs-keyword">var</span> str3 = <span class="hljs-string">&quot;463&quot;</span>;<br><br>str1.padEnd(<span class="hljs-number">3</span>,<span class="hljs-number">0</span>);		<span class="hljs-comment">//&quot;100&quot;			总长度为3，剩下不够的在左边补0</span><br>str2.padEnd(<span class="hljs-number">6</span>,<span class="hljs-number">0</span>);		<span class="hljs-comment">//&quot;560000&quot;		总长度为6，剩下不够的在左边补0</span><br>str3.padEnd(<span class="hljs-number">3</span>,<span class="hljs-number">0</span>);		<span class="hljs-comment">//&quot;463&quot;			总长度为3，原来的长度是够的，所以不用补0</span><br>str3.padEnd(<span class="hljs-number">2</span>,<span class="hljs-number">0</span>);		<span class="hljs-comment">//&quot;463&quot;			总长度为2，原长度超过，不用补</span><br></code></pre></td></tr></table></figure>

</li>
</ol>
<p>上面的21个方法就是我们在平常工作当中所要用到的方法，以后在开发的时候只要是碰到了字符串就要想起这21个方法</p>
<h3 id="Number对象"><a href="#Number对象" class="headerlink" title="Number对象"></a>Number对象</h3><p>Number的包装对象比较简单，只有两个方法经常使用</p>
<ol>
<li><p><code>toString(进制)</code>方法，将数字转换成我们指定进制字符串</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> a = <span class="hljs-number">18</span>;<br>a.toString();			<span class="hljs-comment">//10进制的    &quot;18&quot;</span><br>a.toString(<span class="hljs-number">2</span>);			<span class="hljs-comment">//2进制的结果  &quot;10010&quot;</span><br><span class="hljs-keyword">var</span> b = <span class="hljs-number">255</span>;<br>b.toString(<span class="hljs-number">16</span>);			<span class="hljs-comment">//16进制的结果   &quot;ff&quot;</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>toFixed()</code>将数字转换指定小位数的字符串，结果可以四舍六入五看奇偶</p>
</li>
</ol>
<h3 id="Boolean对象"><a href="#Boolean对象" class="headerlink" title="Boolean对象"></a>Boolean对象</h3><p>Boolean对象内部没有什么特殊的方法，就一个<code>toString()</code>的方法转换成字符串，还有一个<code>valueOf（）</code>方法，没有其它的方法了，在此忽略掉</p>
</li>
</ol>

            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/blog/categories/%E5%89%8D%E7%AB%AF%E7%AC%94%E8%AE%B0/">前端笔记</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/blog/tags/JavaScript/">JavaScript</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">
                  
                    本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！
                  
                </p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/blog/2021/09/27/JavaScript%E7%AC%94%E8%AE%B0-3/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">JavaScript笔记-3</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/blog/2021/09/12/JavaScript%E7%AC%94%E8%AE%B0-1/">
                        <span class="hidden-mobile">JavaScript笔记-1</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  

  
</footer>


  <!-- SCRIPTS -->
  
  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" ></script>
<script  src="/blog/js/events.js" ></script>
<script  src="/blog/js/plugins.js" ></script>

<!-- Plugins -->


  
    <script  src="/blog/js/img-lazyload.js" ></script>
  



  



  <script  src="https://cdn.jsdelivr.net/npm/tocbot@4.12.3/dist/tocbot.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4.3.1/anchor.min.js" ></script>



  <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js" ></script>



  <script  src="/blog/js/local-search.js" ></script>






  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2.0.12/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
      typing(title)
      
    })(window, document);
  </script>









  <script  src="https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js" ></script>
  <script>
    if (window.mermaid) {
      mermaid.initialize({"theme":"default"});
    }
  </script>







<!-- 主题的启动项 保持在最底部 -->
<script  src="/blog/js/boot.js" ></script>


</body>
</html>
